Я пытаюсь понять некоторые части OpenGL. Я должен создать робота, который сделан из нескольких частей. На старте хочу нарисовать 3 кубика подряд. Сначала я хочу нарисовать куб посередине, а после этого остальные два.
Можете ли вы сказать мне, что я сделал не так?
void drawScene(GLFWwindow* window) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);mat4 P=perspective(50.0f*PI/180.0f,aspect,1.0f,50.0f);
mat4 V=lookAt(
vec3(0.0f,0.0f,-15.0f),
vec3(0.0f,0.0f,0.0f),
vec3(0.0f,1.0f,0.0f));
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(value_ptr(P));
glMatrixMode(GL_MODELVIEW);
mat4 M=mat4(1.0f);
glLoadMatrixf(value_ptr(V*M));
glPushMatrix(); //create matrix 1 on the top
Models::cube.drawSolid(); //draw cube on 0,0,0 coords
glTranslatef(3.0, 0.0, 0.0); //apply translation to matrix 1
Models::cube.drawSolid(); //draw cube on 3,0,0 coords
glPopMatrix();
glRotatef(180*PI/180, 1.0, 0.0, 0.0);
glTranslatef(3.0, 0.0, 0.0);
Models::cube.drawSolid();
glfwSwapBuffers(window);
}
И еще один пример, который дает мне такие же неправильные результаты:
void drawScene(GLFWwindow* window) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);mat4 P=perspective(50.0f*PI/180.0f,aspect,1.0f,50.0f);
mat4 V=lookAt(
vec3(0.0f,0.0f,-15.0f),
vec3(0.0f,0.0f,0.0f),
vec3(0.0f,1.0f,0.0f));
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(value_ptr(P));
glMatrixMode(GL_MODELVIEW);
mat4 M=mat4(1.0f);
glLoadMatrixf(value_ptr(V*M));
glPushMatrix(); //Matrix 1 on the top
glPushMatrix(); //Matrix 2 on the top
Models::cube.drawSolid(); //Draw cube on matrix 2
glTranslatef(3.0, 0.0, 0.0); //Apply translation on matrix 2
glPushMatrix(); //Matrix 3 on the top
Models::cube.drawSolid(); //Draw cube on matrix 3
glPopMatrix(); //Matrix 2 on the top
glPopMatrix(); //Matrix 1 on the top
glRotatef(180*PI/180, 1.0, 0.0, 0.0); //Apply translation on matrix 1
glTranslatef(3.0, 0.0, 0.0); //Apply translation on matrix 1
Models::cube.drawSolid(); //Draw cube on matrix 1
glfwSwapBuffers(window);
}
В обоих случаях я должен перевести последний куб для 6.0
вместо 3.0
, Я действительно не понимаю, почему. Мне кажется, что после возврата к матрице 1 я применяю эффект к ним.
Чтобы было ясно, я хочу сделать что-то вроде этого:
Draw Cube in 0,0,0
[]
go to 3,0,0
Draw Cube
[] []
Go back to 0,0,0
Rotate in 180 degrees
Go to -3,0,0
Draw Cube
[] [] []
Вы хотите нарисовать куб в центре, второй куб, переведенный вправо, и третий куб, переведенный влево (вдоль оси X).
Это можно сделать разными способами:
Вы можете нарисовать куб в центре, перейти один шаг вправо и нарисуйте следующий куб и, наконец, идти два шага влево ничья третий куб:
float step = 3.0f;
Models::cube.drawSolid();
glTranslatef( 1.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();
glTranslatef( -2.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();
Вы можете нарисовать куб в центре и сохранить (От себя) модель matirx, иди один шаг вправо и нарисуем следующий куб и наконец восстановим (поп) модель матрицы, иди один шаг влево ничья третий куб:
glPushMatrix();
Models::cube.drawSolid();
glTranslatef( 1.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();
glPopMatrix();
glTranslatef( -1.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();
Наконец то, что вы решили сделать.
Нарисуйте куб в центре и сохраните (От себя) модель matirx, иди один шаг вправо и нарисуем следующий куб и наконец восстановим (поп) матрица модели, повернуть на 180 °, идти один шаг вправо ничья третий куб. Но вы должны вращаться вокруг вектора вверх, который равен (0, 1, 0) в вашем случае, а не вокруг оси X:
glPushMatrix();
Models::cube.drawSolid();
glTranslatef( 1.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();
glPopMatrix();
glRotatef( 180*PI/180, 0.0, 1.0f, 0.0f ); // rotate around the up vector
glTranslatef( 1.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();
Кстати, во втором примере вы помещаете в стек 3 матрицы, но выталкиваете только 2 матрицы. Каждая матрица, помещенная в стек, также должна быть удалена снова. Это означает количество glPushMatrix
а также glPopMatrix
всегда должно быть равным. В противном случае вы либо сложите без конца, либо попытаетесь взять что-то из пустого стека.
Других решений пока нет …