У меня есть эта проблема с отображением моих текстурированных VBO на OpenGLES20 (тестирование на Android Motorola Xoom), где текстуры будут выглядеть так, как если бы они были взяты из одной точки текстуры вместо целой: некоторые будут появляться сплошной серый (эта текстура стены, которую я использую), в то время как другие будут казаться сплошным белым (android robot.png).
Шейдерная программа успешно компилируется и связывается. Модель успешно отображается в правильном положении, а текстуры - нет. Буфер, который отправляется как VBO, кажется, работает достаточно хорошо, я протестировал его как статический float [] в руководстве по SampleGLSurface, чтобы заменить треугольник, и текстура хорошо отображается как с robot.png, так и с my. *
Нет сообщения 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);
Я уже много чего перепробовал, но у меня нет идей!