Какие различия в рендеринге OpenGl существуют между Atrix 4G и другими телефонами Android? - PullRequest
1 голос
/ 23 февраля 2011

Причина, по которой я спрашиваю это, заключается в том, что наше приложение (The Elements) прекрасно работает на Droid и Nexus One, наших двух тестовых телефонах, но не совсем корректно на нашем недавно приобретенном Atrix 4G. То, что рисует, представляет собой искаженную версию того, что следует рисовать, причем все цвета заменяются чередующимися линиями голубого, пурпурного и желтого (приблизительно), что приводит нас к мысли, что один из основных цветов для частиц песка, который должен отображаться отсутствует в зависимости от того, на какой линии он находится. Извините за неясное описание, у нас были изображения, но поскольку у этого аккаунта нет 10 репутации, мы не смогли их опубликовать.

Вот код нашего файла gl.c, который выполняет текстурирование и рендеринг:

/*
 * gl.c
 * --------------------------
 * Defines the gl rendering and initialization
 * functions appInit, appDeinit, and appRender.
 */

#include "gl.h"
#include <android/log.h>

unsigned int textureID;

float vertices[] =
{0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f};
float texture[] =
{0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f};
unsigned char indices[] =
{0, 1, 3, 0, 3, 2};
int texWidth = 1, texHeight = 1;


void glInit()
{
    //Set some properties
    glShadeModel(GL_FLAT);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);

    //Generate the new texture
    glGenTextures(1, &textureID);
    //Bind the texture
    glBindTexture(GL_TEXTURE_2D, textureID);

    //Enable 2D texturing
    glEnable(GL_TEXTURE_2D);
    //Disable depth testing
    glDisable(GL_DEPTH_TEST);

    //Enable the vertex and coord arrays
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);


    //Set tex params
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    //Set up texWidth and texHeight texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, emptyPixels);
    //Free the dummy array
    free(emptyPixels);

    //Set the pointers
    glVertexPointer(2, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, texture);
}

void glRender()
{
    //Check for changes in screen dimensions or work dimensions and handle them
    if(dimensionsChanged)
    {
        vertices[2] = (float) screenWidth;
        vertices[5] = (float) screenHeight;
        vertices[6] = (float) screenWidth;
        vertices[7] = (float) screenHeight;

        texture[2] = (float) workWidth/texWidth;
        texture[5] = (float) workHeight/texHeight;
        texture[6] = (float) workWidth/texWidth;
        texture[7] = (float) workHeight/texHeight;

        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        if (!flipped)
        {
            glOrthof(0, screenWidth, screenHeight, 0, -1, 1); //--Device
        }
        else
        {
            glOrthof(0, screenWidth, 0, -screenHeight, -1, 1); //--Emulator
        }

        dimensionsChanged = FALSE;
        zoomChanged = FALSE;
    }
    else if(zoomChanged)
    {
        texture[2] = (float) workWidth/texWidth;
        texture[5] = (float) workHeight/texHeight;
        texture[6] = (float) workWidth/texWidth;
        texture[7] = (float) workHeight/texHeight;

        zoomChanged = FALSE;
    }
    //__android_log_write(ANDROID_LOG_INFO, "TheElements", "updateview begin");
    UpdateView();
    //__android_log_write(ANDROID_LOG_INFO, "TheElements", "updateview end");

    //Clear the screen
    glClear(GL_COLOR_BUFFER_BIT);

    //Sub the work portion of the tex
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, workWidth, workHeight, GL_RGB, GL_UNSIGNED_BYTE, colors);

    //Actually draw the rectangle with the text on it
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
}

Любые идеи относительно того, в чем разница между Atrix 4G и другими телефонами с точки зрения OpenGL или почему наше приложение делает то, чем оно является в целом, очень ценятся! Заранее спасибо.

Вот пример того, как это выглядит: http://imgur.com/Oyw64

Ответы [ 3 ]

3 голосов
/ 04 апреля 2011

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

Ваш glTexSubImage2D вызов отправляет данные в формате GL_RGB, поэтому я предполагаю, что ваш буфер colors составляет 3 байта на пиксель. Скорее всего, телефоны Droid и Nexus One имеют выравнивание пакетов по умолчанию 1, но Tegra 2 по умолчанию имеет выравнивание 4. Это означает, что ваш 3-байтовый массив может стать не выровненным с тем, что драйвер ожидает после каждой строки сканирования, и байтом или двумя будет пропущен для следующей строки сканирования, в результате чего вы увидите цвета. Причина, по которой это работает с текстурой с степенью двойки, заключается в том, что ваш буфер просто правильно выровнен для следующей строки сканирования. По сути, это та же проблема, что и при загрузке BMP, когда каждая строка развертки должна быть дополнена до 4 байтов независимо от битовой глубины изображения.

Вы можете явно отключить любую упаковку выравнивания, вызвав glPixelStorei(GL_PACK_ALIGNMENT, 1);. Обратите внимание, что изменение этого параметра влияет только на то, как OpenGL интерпретирует данные текстуры, поэтому при изменении этого значения не будет отрисовка снижения производительности. Когда текстура отправляется в графическую подсистему, строки сканирования сохраняются в любом формате, оптимальном для аппаратного обеспечения, но драйвер все равно должен знать, как правильно распаковать ваши данные. Однако, так как вы изменяете данные текстуры каждый кадр, вместо того, чтобы драйвер мог сделать один memcpy() для загрузки всей текстуры, он должен будет сделать TextureHeight *memcpy() s, чтобы загрузить его. Скорее всего, это не будет основным узким местом, но если вы ищете лучшую производительность, вы можете запросить выравнивание пакетов драйвера по умолчанию при запуске, используя glGetIntegerv(GL_PACK_ALIGNMENT, &align);, и соответствующим образом настроить буфер во время выполнения.

Вот справка в glPixelStore () для справки.

1 голос
/ 27 февраля 2011

Хорошо, мы наконец нашли актуальную проблему.Оказывается, что glSubTexImage2D () на самом деле требует, чтобы WIDTH был степенью двойки, но не высотой, для некоторых графических процессоров, включая Tegra 2. Мы думали, что только текстура должна была быть степенью двойки, и вот гдемы были не правы.Нам придется немного перекодировать, но, надеюсь, в конце концов это сработает (ПОСЛЕДНИМ !!).

0 голосов
/ 23 февраля 2011

Atrix 4G - первый известный телефон, использующий графический процессор Tegra от Nvidia.Таким образом, он имеет совершенно другую реализацию OpenGL, чем предыдущие устройства Android.Либо вы наблюдаете ошибку комбинации оборудования и программного обеспечения Tegra, либо ваше приложение полагалось на неопределенное поведение, и вам повезло на других устройствах.

Возможно, вы захотите отправить сообщение об ошибке в Nvidia.

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