OpenGLES2.0如何追踪“纹理是一种统一的颜色”的bug - 需要一些想法。

时间:2011-07-29 07:29:38

标签: android textures opengl-es-2.0

我在OpenGLES20上显示我的纹理VBO时遇到了这个问题(在android motorola Xoom上测试),其中纹理看起来好像是从纹理的单个点而不是整个东西中取出:有些会出现坚实的灰色(我使用的这种墙的纹理),而其他人将显示为纯白色(android robot.png)。

着色器程序成功编译和链接。模型在正确的位置成功显示,但纹理不成功。作为VBO发送的缓冲区似乎工作得很好,我在SampleGLSurface教程上测试它作为静态float []来替换三角形,并且纹理与robot.png和我自己一起很好地显示。

没有glError消息。

为了解决这个问题,我删除了onSurfaceCreated()和onSurfaceChanged()中的所有内容,并缩小为绘制框架中的一包连续GLES20指令。

着色器加载了

 GLES20.glUseProgram(_program);

在drawFrame()方法的开头,不会引发任何错误。

顶点着色器:

uniform mat4 uMVPMatrix;
attribute vec4 aPosition;
attribute vec2 textureCoord;
varying vec2 tCoord;

void main() {
    tCoord = textureCoord;
    gl_Position = uMVPMatrix * aPosition; 
}

片段着色器:

precision mediump float;
uniform sampler2D texture0;
varying vec2 tCoord;

void main() {
    gl_FragColor = texture2D(texture0, tCoord);
}

渲染代码:

if(textureId==null){
    textureId = new int[1];
    Bitmap img = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.texture0);
    GLES20.glGenTextures(1, textureId, 0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId[0]);
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, img, 0);
    GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
    img.recycle();
}

if(!meshisloaded){
    objectLoaderVBO = new ObjectLoaderVBO(mesh.getModelName(), mContext);
    meshisloaded = true;
}

int vboId = objectLoaderVBO.getVboId();
int iboId = objectLoaderVBO.getIboId();
int sizeInFaces = objectLoaderVBO.getSizeInFaces();
int facesSize = 3;
int FLOAT_SIZE_BYTES = 4;
int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 8 * FLOAT_SIZE_BYTES;
int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; 
int TRIANGLE_VERTICES_DATA_TEX_OFFSET = 6; // normals are at 3, 
                                               // but we don't care about normals 
                                               // just for simple texture display 
                                               // without culling, right?
int vertexLoc = GLES20.glGetAttribLocation(shaderProgram, "aPosition");
int texCoordLoc = GLES20.glGetAttribLocation(shaderProgram, "textureCoord");
int mMVPMatrixLoc = GLES20.glGetUniformLocation(shaderProgram, "uMVPMatrix");
int[] textureLocs = null;
textureLocs = new int[1];
textureLocs[0] = GLES20.glGetUniformLocation(shaderProgram, "texture0");
GLES20.glUniformMatrix4fv(mMVPMatrixLoc, 1, false, mMVPMatrix, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId[0]);
GLES20.glUniform1i(textureLocs[0], 0);
GLES20.glEnableVertexAttribArray(vertexLoc);
GLES20.glEnableVertexAttribArray(texCoordLoc);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
GLES20.glVertexAttribPointer(vertexLoc, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES,TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(texCoordLoc, 2, GLES20.GL_FLOAT, true, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, TRIANGLE_VERTICES_DATA_TEX_OFFSET);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, iboId);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, sizeInFaces*facesSize, GLES20.GL_UNSIGNED_SHORT, 0);
GLES20.glDisableVertexAttribArray(vertexLoc);
GLES20.glDisableVertexAttribArray(texCoordLoc);

我已经尝试了很多东西,但我没有想法!

1 个答案:

答案 0 :(得分:1)

您在glVertexAttribPointer中提供的纹理坐标偏移量必须以字节为单位,而不是以组件(浮点数)为单位,因此它应为24或更好6 * FLOAT_SIZE_BYTES。所以你的纹理坐标只是垃圾(从位置和正常部分取得)。

顺便说一句,glVertexAttribPointer的规范化标志仅在提供整数数据时使用,因此不需要为texCoords将其设置为true