OpenGL фиксированные преобразования координат
Я просто пытался сделать рендеринг с OpenGL, и я подумал об этом: как бы вы выполняли преобразования в фиксированной системе координат. Другими словами, если вы вращаете объект вокруг одной оси, вы увидите, что другие тоже будут вращаться? Следовательно, последующие повороты будут выполняться на новой оси построения.
Я прочитал это в документации (см. Часть 9.070) https://www.opengl.org/archives/resources/faq/technical/transformations.htm, но я понятия не имею: 1. если это работает 2. как это реализовать потому что я действительно не понимаю, что я должен делать.
Я думаю, что я не буду единственным, кто захочет сделать это, и это также, я думаю, интересный вопрос.
Изменить: вот реализация, которая не работает, и которую я хотел бы исправить
evoid display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
glMatrixMode(GL_MODELVIEW); // To operate on model-view matrix
// Render a color-cube consisting of 6 quads with different colors
glLoadIdentity(); // Reset the model-view matrix
glTranslatef(1.5f, 0.0f, -7.0f); // Move right and into the screen
//glRotatef(angleCube, 1.0f, 1.0f, 1.0f); // Rotate about (1,1,1)-axis [NEW]
//Matrix a transformation matrix obtained from a Translation, Scale and Rotation composition
// In an other piece of the code I wanted to try
// The matrix is a float[16] and the values are correct and updated every now and then to make the cube rotate
glMultMatrixf(matrix);
glBegin(GL_QUADS); // Begin drawing the color cube with 6 quads
// Top face (y = 1.0f)
// Define vertices in counter-clockwise (CCW) order with normal pointing out
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex3f( 1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
// Bottom face (y = -1.0f)
glColor3f(1.0f, 0.5f, 0.0f); // Orange
glVertex3f( 1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f);
// Front face (z = 1.0f)
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, 1.0f);
// Back face (z = -1.0f)
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex3f( 1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f);
// Left face (x = -1.0f)
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
// Right face (x = 1.0f)
glColor3f(1.0f, 0.0f, 1.0f); // Magenta
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glEnd(); // End of drawing color-cube
1 ответ
Матрица просмотра модели OpenGL работает как стек. Каждое преобразование выполняется путем умножения преобразования на текущую матрицу MVM. Другими словами, это выглядит так:
New_MVM = Old_MVM * Transformation
Это приводит к тому, что преобразования всегда происходят в локальной системе координат. Как говорится в статье, вам нужно преобразование для работы в системе с фиксированными координатами ("глобальные координаты"), поэтому вам нужно предварительно умножить так:
New_MVM = Transformation * Old_MVM
Обратите внимание, что вместо извлечения MVM из OpenGL, как указано в статье, вы можете сохранить матрицу преобразования для объекта в качестве элемента данных. Каждый раз, когда вы хотите преобразовать свой объект, просто предварительно умножьте новое преобразование на старое.
Как только вы предварительно вычислили окончательную матрицу преобразования для вашего объекта, вы можете передать ее в OpenGL, вызвав glMultMatrix.
РЕДАКТИРОВАТЬ: так как вам нужно вычислить матрицу самостоятельно, вам понадобится математическая библиотека. Если вы используете GLM, вы можете сделать это следующим образом:
При вращении вашего объекта:
glm::vec3 axis(x, y, z);
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), angle_in_degrees, axis);
totalTransform = rotation * totalTransform;
Тогда в вашем методе "отображения":
float *matPtr = glm::value_ptr(totalTransform);
glMultMatrixf(matPtr);
Отказ от ответственности: Весь код не проверен.