Попытка нарисовать текстурированные треугольники на устройстве не удалась, но эмулятор работает. Зачем? - PullRequest
10 голосов
/ 22 января 2010

У меня есть серия вызовов 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);

Ответы [ 7 ]

11 голосов
/ 27 ноября 2010

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

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

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

3 голосов
/ 02 февраля 2010

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

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

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

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

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

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


отредактировано:

Я настроил файл 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) {
        }
    }

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

1 голос
/ 18 мая 2011

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

Я пытался отобразить текстуру на вкладке Samsung 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"/>

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

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

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

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

1 голос
/ 01 декабря 2010

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

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

0 голосов
/ 23 мая 2010

вы где-нибудь используете интерфейс 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);

}
0 голосов
/ 01 февраля 2010

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

0 голосов
/ 22 января 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...