OpenGLES2.0 Как отследить ошибку «Текстура - это однородный цвет» - нужны идеи. - PullRequest
0 голосов
/ 29 июля 2011

У меня есть эта проблема с отображением моих текстурированных 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);

Я уже много чего перепробовал, но у меня нет идей!

1 Ответ

1 голос
/ 29 июля 2011

Смещение координат текстуры, которое вы задаете в glVertexAttribPointer, должно быть в байтах, а не в компонентах (с плавающей точкой), поэтому оно должно быть 24 или лучше 6 * FLOAT_SIZE_BYTES. Таким образом, ваши текстурные координаты просто мусор (взятый из позиции и часть из нормальной).

И, кстати, нормализованный флаг glVertexAttribPointer используется только при предоставлении целочисленных данных, поэтому нет необходимости устанавливать его в true для texCoords.

...