Визуализация текстурированных примитивов в Android OpenGL ES 2.0 - Что я делаю не так? - PullRequest
0 голосов
/ 02 января 2012

Я пишу игровой движок с открытым исходным кодом для Android ( здесь ), и у меня возникли проблемы с рендерингом текстурированных треугольников. OpenGL не сообщает об ошибках, но ничего не рендерит. Я могу очень хорошо визуализировать треугольники цвета вершин, поэтому я знаю, что мои функции загрузки VBO и шейдеров работают. У меня такое ощущение, что мне просто не хватает какой-то мелочи. Вот соответствующий код:

// loaded is a boolean field 
if(!loaded ){
    int[] tex = { 0 };
    GLES20.glGenTextures(1, tex, 0);
    int handle = tex[0];

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, handle);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
            GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
            GLES20.GL_CLAMP_TO_EDGE);
    if (useMipmaps) {
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
                GLES20.GL_TEXTURE_MIN_FILTER,
                GLES20.GL_LINEAR_MIPMAP_NEAREST);
    } else {
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
                GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    }
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

    // bmp is an android.graphics.Bitmap object
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
    if (useMipmaps)
        GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
    loaded = true;
}

GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + glTexture);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, handle);
GLES20.glUniform1i(GLES20.glGetUniformLocation(programHandle,
                "s_baseMap"), glTexture);

GLES20.glDrawElements(GLES20.GL_TRIANGLES,
                    indexCount, GLES20.GL_UNSIGNED_SHORT, 0);

Вершинный шейдер:

precision mediump float;

uniform mat4 u_viewProj;
uniform vec3 u_lightColor;

attribute mat4 a_model;
attribute vec4 a_pos;
attribute vec2 a_mtl; // Stores UV coords

varying vec2 v_tc;

void main() {
    gl_Position = (u_viewProj * a_model) * a_pos;
    v_tc = a_mtl;
}

И фрагмент шейдера:

precision mediump float;

varying vec2 v_tc;

uniform sampler2D s_baseMap;

void main() {
    vec4 black = vec4(0.0, 0.0, 0.0, 1.0);
    gl_FragColor = black + texture2D(s_baseMap, v_tc);
}

1 Ответ

0 голосов
/ 05 января 2012

Я решил это. Проблема была не в текстурировании или фрагментном шейдере вообще. Это было так, как атрибут матрицы модели был загружен в вершинный шейдер. Мой код загрузки матрицы был такой:

GLES20.glDisableVertexAttribArray(a_model);
GLES20.glVertexAttrib4fv(a_model, matrix, matrixOffset * 16);
GLES20.glVertexAttrib4fv(a_model, matrix, (matrixOffset * 16) + 4);
GLES20.glVertexAttrib4fv(a_model, matrix, (matrixOffset * 16) + 8);
GLES20.glVertexAttrib4fv(a_model, matrix, (matrixOffset * 16) + 12);

Да, это была часть "ненужного" кода, который я удалил в моем втором редактировании . * Facepalm *

Оказывается, a_model - это местоположение первой строки матрицы модели. Поскольку я загружал данные только в первый ряд, последние три строки матрицы были пустыми, поэтому позиции вершин были перепутаны, а треугольники стали вырожденными. Я исправил это, добавив 1 к a_model для каждой последующей строки, например:

GLES20.glDisableVertexAttribArray(a_model);
GLES20.glDisableVertexAttribArray(a_model + 1);
GLES20.glDisableVertexAttribArray(a_model + 2);
GLES20.glDisableVertexAttribArray(a_model + 3);
GLES20.glVertexAttrib4fv(a_model, matrix, matrixIndex * 16);
GLES20.glVertexAttrib4fv(a_model + 1, matrix, (matrixIndex * 16) + 4);
GLES20.glVertexAttrib4fv(a_model + 2, matrix, (matrixIndex * 16) + 8);
GLES20.glVertexAttrib4fv(a_model + 3, matrix, (matrixIndex * 16) + 12);

Теперь все работает отлично!

...