我在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);
我已经尝试了很多东西,但我没有想法!
答案 0 :(得分:1)
您在glVertexAttribPointer
中提供的纹理坐标偏移量必须以字节为单位,而不是以组件(浮点数)为单位,因此它应为24
或更好6 * FLOAT_SIZE_BYTES
。所以你的纹理坐标只是垃圾(从位置和正常部分取得)。
顺便说一句,glVertexAttribPointer
的规范化标志仅在提供整数数据时使用,因此不需要为texCoords将其设置为true
。