Android OpenGL - 加载的纹理改变颜色
Android OpenGL - loaded textures change color
我正在尝试渲染一个简单的 3D 场景。它基本上是一个包裹在纹理中的表面。我已经在 4 台设备上对其进行了测试,只有一台(Galaxy Note 4)可以正确渲染纹理。其他三款手机(HTC Evo 3D、LG G2、Sony Xperia Z1)使用一种颜色渲染所有纹素的纹理,这似乎是纹理的平均颜色。例如:original image and rendered 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 的幂和非幂),不同的 alpha。
- 尝试切换 on/off 不同的选项,例如:GL_CULL_FACE、GL_BLEND、GL_TEXTURE_MIN(MAG)_FILTER、GL_TEXTURE_WRAP...
- 在每个可能的地方检查 OpenGL 错误。 glGetError() returns 没有错误。
- 检查了调试器中的代码。转换为位图的纹理在加载到 OpenGL 之前和之后看起来都很好。
求助:)
问题已解决。不稳定的行为是由于 onDraw()
中缺少 glEnableVertexAttribArray(texCoordHandle);
调用引起的。注 4 没问题;它只需要启用 positionHandle
(顶点)。其他手机显然不高兴。也许是因为 Note 4 支持 GL ES 3.1?
谢谢你的时间。
我正在尝试渲染一个简单的 3D 场景。它基本上是一个包裹在纹理中的表面。我已经在 4 台设备上对其进行了测试,只有一台(Galaxy Note 4)可以正确渲染纹理。其他三款手机(HTC Evo 3D、LG G2、Sony Xperia Z1)使用一种颜色渲染所有纹素的纹理,这似乎是纹理的平均颜色。例如:original image and rendered 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 的幂和非幂),不同的 alpha。
- 尝试切换 on/off 不同的选项,例如:GL_CULL_FACE、GL_BLEND、GL_TEXTURE_MIN(MAG)_FILTER、GL_TEXTURE_WRAP...
- 在每个可能的地方检查 OpenGL 错误。 glGetError() returns 没有错误。
- 检查了调试器中的代码。转换为位图的纹理在加载到 OpenGL 之前和之后看起来都很好。
求助:)
问题已解决。不稳定的行为是由于 onDraw()
中缺少 glEnableVertexAttribArray(texCoordHandle);
调用引起的。注 4 没问题;它只需要启用 positionHandle
(顶点)。其他手机显然不高兴。也许是因为 Note 4 支持 GL ES 3.1?
谢谢你的时间。