Пустой экран Android Native GLES 2.0 с матрицей MVP

#android #c #matrix #opengl-es #projection

#Android #c #Матрица #opengl-es #проекция

Вопрос:

Я рисую простой четырехъядерный процессор, используя gles2.0 на c . Если я нарисую его с помощью базового вершинного шейдера, проблем не возникнет, и это результат

введите описание изображения здесь

 uniform mat4 u_mvp;
attribute vec4 a_Position;
void main(){
   gl_Position = a_Position;
}
 

если я добавлю матрицу MVP

 gl_Position = u_mvp * a_Position;
 

тогда на экране ничего нет.

Это и есть перспективная матрица:

 Matrix4 Matrix4::getPerspective(float angle, float ratio, float near, float far) {
    // angle = 45; ratio = 1.438; near = 1; far = 100
    Matrix4 matrix;

    float top = (float)(near * Math::tangentDegrees(angle / 2.0f));
    float bottom = -top;

    float right = top * ratio;
    float left = -right;

    matrix.m[0] = (2 * near) / (right - left);
    matrix.m[1] = 0.0f;
    matrix.m[2] = (right   left) / (right - left);
    matrix.m[3] = 0.0f;

    matrix.m[4] = 0.0f;
    matrix.m[5] = (2 * near) / (top - bottom);
    matrix.m[6] = (top   bottom) / (top - bottom);
    matrix.m[7] = 0.0f;

    matrix.m[8] = 0.0f;
    matrix.m[9] = 0.0f;
    matrix.m[10] = -(far   near) / (far - near);
    matrix.m[11] = -(2 * far * near) / (far - near);

    matrix.m[12] = 0.0f;
    matrix.m[13] = 0.0f;
    matrix.m[14] = -1.0f;
    matrix.m[15] = 0.0f;

    return matrix;
}
 

Матрица ModelView получается следующим образом:

 modelView = translation * rotation * scale
mvp = perspective * modelView
 

Каждый элемент этого умножения выполняется в следующем примере
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices /

и все они инициализируются в матрице идентификаторов.

С помощью этой команды я получаю дескриптор

 transformUniformHandle = (GLuint)glGetUniformLocation(getProgramId(), "u_mvp");
 

С помощью этой команды я установил матрицу mvp в шейдере (пробовал оба GL_FALSE, GL_TRUE)

 glUniformMatrix4fv(transformUniformHandle, 1, GL_TRUE, modelViewProjection.m);
 

Ответ №1:

OpenGL использует хранилище по основным столбцам для матриц, в то время как ваша проекционная матрица настраивается в порядке следования строк. Итак, вам нужно перенести порядок элементов матрицы:

 matrix.m[0] = (2 * near) / (right - left);
matrix.m[4] = 0.0f;
matrix.m[8] = (right   left) / (right - left);
matrix.m[12] = 0.0f;

matrix.m[1] = 0.0f;
matrix.m[5] = (2 * near) / (top - bottom);
matrix.m[9] = (top   bottom) / (top - bottom);
matrix.m[13] = 0.0f;

matrix.m[2] = 0.0f;
matrix.m[6] = 0.0f;
matrix.m[10] = -(far   near) / (far - near);
matrix.m[14] = -(2 * far * near) / (far - near);

matrix.m[3] = 0.0f;
matrix.m[7] = 0.0f;
matrix.m[11] = -1.0f;
matrix.m[15] = 0.0f;
 

Вы пытались перенести матрицу, передав GL_TRUE ее в качестве 3-го аргумента здесь:

 glUniformMatrix4fv(transformUniformHandle, 1, GL_TRUE, modelViewProjection.m);
 

Это не поддерживается в ES 2.0, единственным допустимым значением аргумента является GL_FALSE . GL_INVALID_VALUE При вызове glGetError() после этого вы увидите сообщение об ошибке. Вызов glGetError() должен быть обычным, если у вас возникли проблемы с вашим кодом OpenGL.

Вы могли бы сохранить основную строку матрицы, если бы действительно захотели, и соответствующим образом изменить код шейдера, умножив вектор справа:

 gl_Position = a_Position * u_mvp;
 

Но, вероятно, лучше просто использовать порядок следования столбцов для ваших матриц.

Кроме того, вы не показываете свою матрицу представления модели. Вам нужно будет убедиться, что преобразование вида преобразует геометрию в отрицательном направлении z, чтобы она располагалась между ближней и дальней плоскостями используемого вами преобразования проекции.

Ответ №2:

Учитывая, что вы не показали весь свой код, я не могу быть уверен, но, возможно, вы не вызывали glUseProgram перед вызовом glUniformMatrix4fv. Также может случиться так, что ваши треугольники вырезаны матрицей проекции. Убедитесь, что точки находятся в пределах диапазона отсечения. Если это не исправит проблему, вы должны получать ошибки от glGetError. На этой странице будет объяснено его использование: проверка ошибок OpenGL

Комментарии:

1. Спасибо за ваш ответ. Я не могу опубликовать весь код, потому что объектов много, и это будет очень много. Вызывается glUseProgram, на самом деле код работает, если я не использую mvp.