Я пробовал простую программу, которая динамически генерирует текстуру и сопоставляет ее с квадрантом с использованием NDK. Все в порядке на эмуляторе, но не на реальных устройствах. Вот мой код:Невозможно сопоставить текстуры с OpenGL ES на реальных устройствах
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 х 32, но ни один из них не работает.
Может ли кто-нибудь помочь мне понять, почему отображение текстур происходит не на реальных устройствах? Есть ли ограничение по графику или что-то еще?
EDIT: Я попробовал предложение Spoon и нашел настоящую проблему. Независимо от того, какую текстуру я связываю, устройство использует текстуру с именем для рендеринга квадрациклов, поэтому glBindTexture(GL_TEXTURE_2D, 0)
отлично работает, но glBindTexture(GL_TEXTURE_2D, 1)
и все, что возвращается glGenTextures(...)
. Это означает, что я могу сохранить только одну текстуру, но мне нужно использовать 2 или более.
Спасибо за ответ. Я проверил значение, возвращаемое 'glGenTextures()'. Это действительно вызывало случайные числа, превышающие 100 000. Я использовал вручную номер 0, и он сработал! В соответствии с [документацией] (http://www.khronos.org/opengles/documentation/opengles1_0/html/glBindTexture.html) 0 представляется зарезервированным именем текстуры, которое _представляет текстуру по умолчанию для каждой целевой текстуры и _если связаны к ним при инициализации, поэтому я сначала попробовал 1, но не смог. –
Все еще есть проблемы, см. EDIT. –
В 'init()' вы должны вызвать 'glBindTexture()' после 'glGenTexture' (или вручную назначить идентификатор), а затем установить параметры текстуры. Вероятно, поэтому он не работает, поскольку вы не устанавливаете параметры текстуры, кроме первой текстуры. Добавил мою реализацию к моему ответу. Моя все в джаве, но это не имеет значения. Работы по разгоревшему огню 2.3.4. –