У меня есть серия вызовов OpenGL-ES, которые правильно отображают треугольник и текстурируют его с помощью альфа-смешивания на эмуляторе (2.0.1). Когда я запускаю тот же код на реальном устройстве (Droid 2.0.1), все, что я получаю, это белые квадраты.
Это говорит о том, что текстуры не загружаются, но я не могу понять, почему они не загружаются. Все мои текстуры - это 32-битные PNG с альфа-каналами в формате res / raw, поэтому они не оптимизированы в соответствии с sdk docs .
Вот как я загружаю свои текстуры:
private void loadGLTexture(GL10 gl, Context context, int reasource_id, int texture_id)
{
//Get the texture from the Android resource directory
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), reasource_id, sBitmapOptions);
//Generate one texture pointer...
gl.glGenTextures(1, textures, texture_id);
//...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[texture_id]);
//Create Nearest Filtered Texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
//Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
//Clean up
bitmap.recycle();
}
Вот как я рендерил текстуру:
//Clear
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
//Enable vertex buffer
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
//Push transformation matrix
gl.glPushMatrix();
//Transformation matrices
gl.glTranslatef(x, y, 0.0f);
gl.glScalef(scalefactor, scalefactor, 0.0f);
gl.glColor4f(1.0f,1.0f,1.0f,1.0f);
//Bind the texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[textureid]);
//Draw the vertices as triangles
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);
//Pop the matrix back to where we left it
gl.glPopMatrix();
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
И вот опции, которые я включил:
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA);
Редактировать: я только что попытался предоставить BitmapOptions для вызова BitmapFactory.decodeResource (), но, похоже, это не решает проблему, несмотря на ручную настройку одинаковых предпочтительных параметров конфигурации, плотности и целевой плотности.
Edit2: по запросу, вот скриншот работы эмулятора. Нижележащие треугольники показаны с текстурой окружности, прозрачность работает, потому что вы можете видеть черный фон.
удалена мертвая ссылка ImageShack
Вот пример того, что делает дроид с точно таким же кодом:
удалена мертвая ссылка ImageShack
Edit3:
Вот мои BitmapOptions, обновленные вызов выше, как я сейчас вызываю BitmapFactory, все еще те же результаты, что и ниже:
sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
sBitmapOptions.inDensity = 160;
sBitmapOptions.inTargetDensity = 160;
sBitmapOptions.inScreenDensity = 160;
sBitmapOptions.inDither = false;
sBitmapOptions.inSampleSize = 1;
sBitmapOptions.inScaled = false;
Вот мои вершины, координаты текстуры и индексы:
/** The initial vertex definition */
private static final float vertices[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f
};
/** The initial texture coordinates (u, v) */
private static final float texture[] = {
//Mapping coordinates for the vertices
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f
};
/** The initial indices definition */
private static final byte indices[] = {
//Faces definition
0,1,3, 0,3,2
};
Есть ли способ сбросить содержимое текстуры после ее загрузки в OpenGL ES? Может быть, я могу сравнить загруженную текстуру эмулятора с фактической загруженной текстурой устройства?
Я попробовал использовать другую текстуру (значок андроида по умолчанию), и снова, он отлично работает на эмуляторе, но не может отобразиться на реальном телефоне.
Edit4: пробовал переключаться при загрузке текстур. Неудачно. Пробовал использовать постоянное смещение от 0 до glGenTextures, без изменений.
Есть ли что-то, что я использую, что эмулятор поддерживает то, чего нет у реального телефона?
Edit5: В соответствии с Райаном ниже, я изменил текстуру с 200x200 до 256x256, и проблема НЕ была решена.
Редактировать: По запросу добавлены вызовы к glVertexPointer и glTexCoordPointer выше. Кроме того, вот инициализация vertexBuffer, textureBuffer и indexBuffer:
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
loadGLTextures(gl, this.context);