Пытается нарисовать текстурированные треугольники на устройстве, но эмулятор работает. Зачем?

У меня есть серия вызовов OpenGL-ES, которые правильно отображают треугольник и текстурируют его с альфа-смешиванием на эмуляторе (2.0.1). Когда я запускаю тот же код на самом устройстве (Droid 2.0.1), все, что я получаю, это белые квадраты.

Это говорит мне, что текстуры не загружаются, но я не могу понять, почему они не загружаются. Все мои текстуры представляют собой 32-разрядные PNG-файлы с альфа-каналами под res / raw, поэтому они не оптимизированы для документов sdk .

Вот как я загружаю свои текстуры:

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, eg 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? Может быть, я могу сравнить загруженную текстуру эмулятора с загруженной текстурой устройства?

Я попробовал с другой текстурой (значок по умолчанию для Android), и опять же, он отлично работает для эмулятора, но не отображается на реальном телефоне.

Edit4: Попробовал переключение, когда я загружаю текстуру. Не повезло. Пробовал использовать постоянное смещение от 0 до glGenTextures, без изменений.

Есть ли что-то, что я использую, что эмулятор поддерживает то, что на самом деле нет?

Edit5: Per Ryan ниже, я изменил размер моей текстуры с 200×200 до 256×256, и проблема не была решена.

Изменить: по запросу добавлены вызовы 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); 

Я также новичок в Android OpenGL ES dev. У меня есть Milestone (евро версия для Droid).

Из того, что я вижу до сих пор, выпустив несколько обучающих приложений из разных книг / веб-сайтов на моей вехе, кажется, что этот телефон обрабатывает OpenGL ES по-другому, чем все другие выпущенные на сегодняшний день телефоны Android.

Я думаю, что это связано с расширениями OpenGL, поддерживаемыми на устройстве.

Проверьте эту ссылку на список поддерживаемых расширений, я уверен, что гуру кода обнаружит, почему именно дроид обрабатывает opengls таким странным образом.

http://www.rbgrn.net/content/345-hands-on-motorola-droid-opengl-es-specs

Надеюсь это немного поможет


EDITED:

Я изменил manifest.xml и заметил, что при использовании

 <uses-sdk android:minSdkVersion="6"/> 

Ресурсы не загружаются вообще.

Когда используешь

 <uses-sdk android:minSdkVersion="3"/> 

Ресурсы загружаются штрафом.

Поэтому я переключился на

 <uses-sdk android:minSdkVersion="6"/> 

И изменил способ загрузки растрового изображения.

Попробуйте заменить:

  //Get the texture from the Android resource directory Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), reasource_id, sBitmapOptions); 

с :

 InputStream is = context.getResources().openRawResource(your.resource.there); Bitmap bitmap = null; try { bitmap = BitmapFactory.decodeStream(is); } finally { //Always clear and close try { is.close(); is = null; } catch (IOException e) { } } 

Текстуры загружаются отлично на моей вехе с помощью этого кода, надеюсь, что эта работа для вас!

У меня была именно эта проблема, когда я перешел с SDK 3 на 4. Мои текстуры отображались на эмуляторе, но не на реальном устройстве (Motorola Milestone / Droid).

Все ваши текстуры должны быть двоичными. Шахта была 256х256. Однако причина, по которой текстуры не отображаются, заключается в том, что ОС масштабирует их по размерам бинарных мощностей для отображения на экране высокой плотности Milestone.

Решение легко – просто переместите текстуры в каталог drawable-nodpi, и ОС не будет масштабировать их при загрузке.

Убедитесь, что вы загрузили свои растровые изображения с помощью соответствующего BitmapConfig, который не масштабирует ваш образ за кулисами, потому что это происходит.

Кроме того, есть причина, по которой вы храните свои png в / raw / вместо / drawable /?

Редактированный ответ Dullahx решил мою проблему по той же проблеме. Большое спасибо, это прослушивало меня последние два дня!

Я пытался отобразить текстуру на вкладке galaxy galaxy, которая была успешно отображена на эмуляторе, но на дисплее отображалась только плоскость.

Я заменил свой код:

 plane.loadBitmap(BitmapFactory.decodeResource(getResources(),R.drawable.jay)); 

с этим:

 InputStream is = context.getResources().openRawResource(R.drawable.jay); // Load the texture. plane.loadBitmap(BitmapFactory.decodeStream(is)); 

И он тоже работал на устройстве!

Но будьте осторожны с minSdkVersion, если вы также пытаетесь сопоставить текстуру в полноэкранном прямоугольнике размера, таком как я. Если я использую

  <uses-sdk android:minSdkVersion="3"/> 

На вкладке galaxy galaxy мой самолет не был показан в полноэкранном режиме. Он был отображен в соответствии с полноэкранным размером устройства с использованием SDK версии 3. Я изменил это на

 <uses-sdk android:minSdkVersion="8"/> 

И мой полноэкранный прямоугольник вернулся со своей текстурой.

Надеюсь, это тоже поможет.

Я не уверен в вашей проблеме, я довольно новичок в развитии в целом, но мои проблемы с OpenGL и различие между эмулятором и телефоном были:

-Emulator может поддерживать размеры не 2 ^ x для растровых изображений, телефон не может отображать экран в NDK для openGL, поэтому мне нужно было использовать отрицательные координаты для определения представления в эмуляторе, в то время как мой G1 использовал неотрицательные координаты.

Надеюсь, это поможет вам каким-то образом.

Я думаю, возможно, что у вас возникли проблемы с загрузкой текстуры из APK. Попробуйте скопировать текстуру на SDCard и посмотреть, можете ли вы ее загрузить.

Вы используете интерфейс GL11 где-нибудь? GL11 не поддерживается всеми устройствами. А также удалить строку glColor, возможно, ваша текстура отображается, но окрашена цветом? Здесь некоторый фрагмент кода, как я показываю свои текстурные сетки:

 void draw(GL10 gl) { // Enabled the vertices buffer for writing and to be used during // rendering. gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // Specifies the location and data format of an array of vertex // coordinates to use when rendering. gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); gl.glEnable(GL10.GL_TEXTURE_2D); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); gl.glBindTexture(GL10.GL_TEXTURE_2D, myTextureId); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); gl.glDrawArrays(drawMode, 0, verticesCount); gl.glDisable(GL10.GL_TEXTURE_2D); // Disable the vertices buffer. gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); }