Я пробовал простую программу, которая динамически генерирует текстуру и отображает ее на четырехугольник, используя NDK. На эмуляторе все нормально, но на реальных устройствах не получилось.
Вот мой код:
private static class Renderer implements GLSurfaceView.Renderer
{
@Override
public void onDrawFrame(GL10 gl)
{
nativeDrawFrame();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
nativeInit(width, height);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
// do nothing...
}
}
и собственный код:
const static GLfloat vertices_f[4][2] =
{
{ 0.0f, 0.0f },
{ 100.0f, 0.0f },
{ 100.0f, 100.0f },
{ 0.0f, 100.0f }
};
const static GLfloat texCoords_f[4][2] =
{
{ 0.0f, 0.0f },
{ 1.0f, 0.0f },
{ 1.0f, 1.0f },
{ 0.0f, 1.0f }
};
JNIEXPORT void JNICALL Java_com_sangfor_gltest_GLView_nativeInit(JNIEnv * env, jobject obj, jint width, jint height)
{
if (!bitmap)
{
// allocate dynamic texture memory
bitmap = memalign(16, 1024*1024);
if (!bitmap)
{
__android_log_print(ANDROID_LOG_ERROR, "native-render", "failed allocation.");
return;
}
}
glViewport(0, 0, width, height);
//glMatrixMode(GL_PROJECTION);
//glLoadIdentity();
//glOrthox(0, 0x10000, 0, 0x10000, 0x10000, -0x10000);
//glClearColorx(0, 0, 0, 0);
glGenTextures(1, &texture);
__android_log_print(ANDROID_LOG_INFO, "native-render", "texture = %d", texture);
// glVertexPointer(2, GL_FIXED, 0, vertices);
// glTexCoordPointer(2, GL_FIXED, 0, texCoords);
//glEnableClientState(GL_COLOR_ARRAY);
glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
glEnable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glDisable(GL_ALPHA_TEST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
JNIEXPORT void JNICALL Java_com_sangfor_gltest_GLView_nativeDrawFrame(JNIEnv * env, jobject obj)
{
struct timeval tv;
unsigned char color_value;
glClear(GL_COLOR_BUFFER_BIT);
// fill texture according to current timestamp
gettimeofday(&tv, NULL);
color_value = (unsigned char)(tv.tv_usec * 0.000255f);
memset(bitmap, color_value, 1024*1024);
__android_log_print(ANDROID_LOG_INFO, "native-render", "color_value = %d", color_value);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, bitmap);
glBindTexture(GL_TEXTURE_2D, texture);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords_f);
glVertexPointer(2, GL_FLOAT, 0, vertices_f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glFlush();
}
В эмуляторе все работает так, как я ожидал: область на экране постоянно меняет свой цвет.
Тем не менее, когда я запускаю его на реальных устройствах (Samsung Galaxy S 2.3.3 и Asus Transformer TF101 3.2.1), он просто показывает белый блок и отображение текстуры кажется не работающим.
Я попытался добавить и закомментировать проекционное преобразование, включить отображение текстур, вызвав glEnable(GL_TEXTURE_2D)
, отключить альфа-смешивание и тестирование, вызвав glDisable(...)
, переместить glBindTexture
и glTexImage2D
в функцию инициализации, изменить размер текстуры на 32 x 32 но ничего из этого не работает.
Может кто-нибудь помочь мне понять, почему наложение текстур не работает только на реальных устройствах? Есть ограничение GPU или что-то?
РЕДАКТИРОВАТЬ: Я попробовал предложение Ложка и нашел реальную проблему. Независимо от того, какую текстуру я привязываю, устройство использует текстуру с именем 0 для рендеринга четырехугольников, поэтому glBindTexture(GL_TEXTURE_2D, 0)
работает нормально, но glBindTexture(GL_TEXTURE_2D, 1)
и все, что возвращается glGenTextures(...)
, не выполняется. Это означает, что я могу сохранить только одну текстуру, но мне нужно использовать 2 или более.