Atrix 4G和其他Android手机在OpenGl渲染方面有什么不同?

Atrix 4G和其他Android手机在OpenGl渲染方面有什么不同?,android,opengl-es,Android,Opengl Es,我问这个问题的原因是,我们的应用程序(元素)在Droid和Nexus One上运行良好,这是我们的两款测试手机,但在我们最近收购的Atrix 4G上运行不正常。“绘制”是“应该绘制”的一个扭曲版本,所有颜色都被青色、品红色和黄色(近似)的交替线条所取代,这让我们相信,根据它所在的线条,应该显示的沙粒的一种原色丢失了。很抱歉描述不清楚,我们有图片,但由于该帐户没有10个声誉,我们无法发布它们 以下是我们的gl.c文件的代码,该文件进行纹理处理和渲染: /* * gl.c * ---------

我问这个问题的原因是,我们的应用程序(元素)在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);
}
/*
*德国劳埃德船级社
* --------------------------
*定义gl渲染和初始化
*函数appInit、appDeinit和appender。
*/
#包括“gl.h”

#include

Atrix 4G是第一款使用Nvidia Tegra GPU的知名手机。因此,它的OpenGL实现与以前的Android设备完全不同。您可能正在观察Tegra硬件+软件组合中的错误,或者您的应用程序依赖于未定义的行为,而您在其他设备上却很幸运


您可能需要向Nvidia提交错误报告。

Atrix 4G是第一款使用Nvidia Tegra GPU的知名手机。因此,它的OpenGL实现与以前的Android设备完全不同。您可能正在观察Tegra硬件+软件组合中的错误,或者您的应用程序依赖于未定义的行为,而您在其他设备上却很幸运


您可能需要向Nvidia提交错误报告。

好的,我们终于找到了实际问题。事实证明,对于某些GPU(包括Tegra 2),glSubTexImage2D()实际上要求宽度为2的幂,而不是高度。我们认为只有纹理需要二的幂,这就是我们错的地方。我们将不得不做一些重新编码,但希望这最终会成功(终于!!)。

好的,我们终于找到了实际问题。事实证明,对于某些GPU(包括Tegra 2),glSubTexImage2D()实际上要求宽度为2的幂,而不是高度。我们认为只有纹理需要二的幂,这就是我们错的地方。我们将不得不进行一些重新编码,但希望这最终会成功(终于!!)。

我知道现在回复有点晚,但您看到混合颜色的真正原因是OpenGL的扫描线布局对齐,而不是任何驱动程序错误或两种大小的纹理问题

您的
glTexSubImage2D
调用正在以
GL_RGB
格式发送数据,因此我猜您的
颜色
缓冲区是每像素3字节。Droid和Nexus One手机的默认组对齐方式可能是1,但Tegra 2的默认组对齐方式是4。这意味着您的3字节阵列可能会在每次扫描线之后与驱动程序预期的不一致,并且下一次扫描线将跳过一两个字节,从而导致您看到的颜色。之所以使用两倍大小的纹理,是因为在下一条扫描线中,缓冲区恰好正确对齐。基本上,这与加载BMP的问题相同,在BMP中,无论图像的位深度如何,每个扫描线都必须填充到4字节

通过调用
glPixelStorei(GL\u PACK\u alignment,1),可以显式禁用任何对齐打包。请注意,更改此值只会影响OpenGL解释纹理数据的方式,因此更改此值不会对渲染造成性能损失。当纹理被发送到图形子系统时,扫描线以适合硬件的任何格式存储,但是驱动程序仍然需要知道如何正确地解压缩数据。但是,由于您每帧都在更改纹理数据,因此驱动程序无法执行一个
memcpy()
来上载整个纹理,而必须执行TextureHeight*
memcpy()
s才能上载纹理。这可能不是一个主要的瓶颈,但如果您正在寻找最佳性能,您可能希望在启动时使用
glGetIntegerv(GL\u pack\u alignment,&align)查询驱动程序的默认包对齐方式
并在运行时相应地调整缓冲区


以下是供参考的示例。

我知道现在回复有点晚,但您看到混合颜色的真正原因是OpenGL的扫描线布局对齐,而不是由于任何驱动程序错误或两种大小的纹理问题

您的
glTexSubImage2D
调用正在以
GL_RGB
格式发送数据,因此我猜您的
颜色
缓冲区是每像素3字节。Droid和Nexus One手机的默认组对齐方式可能是1,但Tegra 2的默认组对齐方式是4。这意味着您的3字节阵列可能会在每次扫描线之后与驱动程序预期的不一致,并且下一次扫描线将跳过一两个字节,从而导致您看到的颜色。之所以使用两倍大小的纹理,是因为在下一条扫描线中,缓冲区恰好正确对齐。基本上,这与加载BMP的问题相同,在BMP中,无论图像的位深度如何,每个扫描线都必须填充到4字节

通过调用
glPixelStorei(GL\u PACK\u alignment,1),可以显式禁用任何对齐打包。请注意,更改此值只会影响OpenGL解释纹理数据的方式,因此更改此值不会对渲染造成性能损失。当纹理被发送到图形子系统时,扫描线以适合硬件的任何格式存储,但是驱动程序仍然需要知道如何正确地解压缩数据。但是,由于您正在更改te