【问题标题】:Android OpenGL - loaded textures change colorAndroid OpenGL - 加载的纹理改变颜色
【发布时间】:2015-12-07 17:17:04
【问题描述】:

我正在尝试渲染一个简单的 3D 场景。它基本上是一个包裹在纹理中的表面。我已经在 4 台设备上对其进行了测试,只有一台(Galaxy Note 4)能够正确渲染纹理。其他三部手机(HTC Evo 3D、LG G2、索尼 Xperia Z1)用一种颜色渲染纹理,所有纹理像素似乎是纹理的平均颜色。例如:original imagerendered texture

我的第一个猜测是我的片段着色器有问题。但它非常基础,抄自《OpenGL ES 2 for Android》一书:

private final String vertexShaderCode =
        "uniform mat4 uMVPMatrix;"+
                "attribute vec4 vPosition;"+
                "attribute vec2 a_TextureCoordinates;"+
                "varying vec2 v_TextureCoordinates;"+
                "void main()"+
                "{"+
                "v_TextureCoordinates = a_TextureCoordinates;"+
                "gl_Position = uMVPMatrix * vPosition;"+
                "}";

private final String fragmentShaderCode =
        "precision mediump float;"+
                "uniform sampler2D u_TextureUnit;"+
                "varying vec2 v_TextureCoordinates;"+
                "void main()"+
                "{"+
                "gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);"+
                "}";

加载纹理:

texCoordHandle = glGetAttribLocation(program, "a_TextureCoordinates");
texUnitHandle = glGetUniformLocation(program, "u_TextureUnit");

texHandle = new int[1];
glGenTextures(1, texHandle, 0);

BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inScaled = false;
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
                       R.drawable.way_texture_pink_square_512, opt);

glBindTexture(GL_TEXTURE_2D, texHandle[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
glGenerateMipmap(GL_TEXTURE_2D);
bitmap.recycle();
glBindTexture(GL_TEXTURE_2D, 0);

我将顶点和纹理坐标保存在不同的浮点缓冲区中,并在循环中绘制它们:

glUseProgram(program);
glUniformMatrix4fv(mvpMatrixHandle, 1, false, vpMatrix, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texHandle[0]);
glUniform1i(texUnitHandle, 0);
glEnableVertexAttribArray(positionHandle);
WaySection[] ws = waySects.get(currWaySect);

for( int i = 0 ; i < ws.length ; i++ ) {
    glVertexAttribPointer(
            positionHandle, COORDS_PER_VERTEX,
            GL_FLOAT, false,
            vertexStride, ws[i].vertexBuffer);

    glVertexAttribPointer(texCoordHandle, COORDS_PER_TEX_VER,
            GL_FLOAT, false,
            texStride, ws[i].texBuffer);

    glDrawArrays(GL_TRIANGLE_FAN, 0,
            ws[i].vertices.length / COORDS_PER_VERTEX);
}

glDisableVertexAttribArray(positionHandle);

我做了什么:

  • 更改了纹理,尝试了不同的尺寸(2 的幂和非 2 的幂),不同的 alpha。
  • 尝试打开/关闭不同的选项,例如:GL_CULL_FACE、GL_BLEND、GL_TEXTURE_MIN(MAG)_FILTER、GL_TEXTURE_WRAP...
  • 在所有可能的地方检查 OpenGL 错误。 glGetError() 不返回错误。
  • 在调试器中检查了代码。转换为位图的纹理在加载到 OpenGL 之前和之后看起来都很好。

请帮忙:)

【问题讨论】:

  • 纹理坐标使用什么值?如果它们距离零还有很长的路要走,那么一些 GPU 可能会遇到精度问题。
  • 我已经检查了 0、0.5 和 1。最终,不是 1,而是更高的整数。

标签: android opengl-es textures opengl-es-2.0


【解决方案1】:

问题解决了。不稳定的行为是由 onDraw() 中缺少 glEnableVertexAttribArray(texCoordHandle); 调用引起的。 Note 4 没问题;它只需要启用positionHandle(顶点)。其他手机显然并不高兴。也许是因为 Note 4 支持 GL ES 3.1? 感谢您的宝贵时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多