в настоящее время я изучаю теорию 3D-рендеринга с помощью книги «Изучение современного программирования 3D-графики» и прямо сейчас застрял в одном из заданий «Дальнейшее изучение» по обзору главы 4, особенно последнего задания.
Ответ на третье действие был дан в этом вопросе., понял без проблем. Однако в этом последнем упражнении меня просят сделать все это на этот раз, используя только матрицы.
У меня есть решение, которое частично работает, но мне кажется, что это хакерство и, вероятно, неправильный способ сделать это.
Мое решение третьего вопроса заключалось в том, чтобы осциллировать компоненты x, y и z трехмерного вектора E
в произвольном диапазоне и создать куб с увеличением и уменьшением масштаба (растущий снизу слева на исходную точку OpenGL). Я хотел сделать это снова с помощью матриц, это выглядело так:
Однако я получаю такие результаты с матрицами (игнорируя изменение цвета фона):
Теперь к коду ...
Матрица представляет собой число с плавающей запятой [16], называемое theMatrix
, которое представляет собой матрицу 4x4 с данными, записанными в порядке по столбцам, со всеми, кроме следующих элементов, инициализированными нулем:
float fFrustumScale = 1.0f; float fzNear = 1.0f; float fzFar = 3.0f;
theMatrix[0] = fFrustumScale;
theMatrix[5] = fFrustumScale;
theMatrix[10] = (fzFar + fzNear) / (fzNear - fzFar);
theMatrix[14] = (2 * fzFar * fzNear) / (fzNear - fzFar);
theMatrix[11] = -1.0f;
тогда остальная часть кода остается такой же, как matrixPerspective обучающий урок, пока мы не перейдем к void display()
функции:
//Hacked-up variables pretending to be a single vector (E)
float x = 0.0f, y = 0.0f, z = -1.0f;
//variables used for the oscilating zoom-in-out
int counter = 0;
float increment = -0.005f;
int steps = 250;
void display()
{
glClearColor(0.15f, 0.15f, 0.2f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(theProgram);
//Oscillating values
while (counter <= steps)
{
x += increment;
y += increment;
z += increment;
counter++;
if (counter >= steps)
{
counter = 0;
increment *= -1.0f;
}
break;
}
//Introduce the new data to the array before sending as a 4x4 matrix to the shader
theMatrix[0] = -x * -z;
theMatrix[5] = -y * -z;
//Update the matrix with the new values after processing with E
glUniformMatrix4fv(perspectiveMatrixUniform, 1, GL_FALSE, theMatrix);
/*
cube rendering code ommited for simplification
*/
glutSwapBuffers();
glutPostRedisplay();
}
А вот код вершинного шейдера, использующий матрицу:
#version 330
layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;
smooth out vec4 theColor;
uniform vec2 offset;
uniform mat4 perspectiveMatrix;
void main()
{
vec4 cameraPos = position + vec4(offset.x, offset.y, 0.0, 0.0);
gl_Position = perspectiveMatrix * cameraPos;
theColor = color;
}
Что я делаю не так или что путаю? Спасибо за то, что вы все это прочитали.