Я пытаюсь понять матрицы OpenGL MVP, и в качестве упражнения я хотел бы нарисовать прямоугольник, заполняющий мое окно, используя матрицы. Я думал, что легко найду учебник для этого, но все те, которые я нашел, просто помещают случайные значения в их настройки матриц MVP.
Скажем, у моего прямоугольника есть эти координаты:
GLfloat vertices[] = {
-1.0f, 1.0f, 0.0f, // Top-left
1.0f, 1.0f, 0.0f, // Top-right
1.0f, -1.0f, 0.0f, // Bottom-right
-1.0f, -1.0f, 0.0f, // Bottom-left
};
Вот мои 2 треугольника:
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};
Если я нарисую прямоугольник с идентичными матрицами MVP, он заполняет экран, как и ожидалось. Теперь я хочу использовать усеченный конус. Вот его настройки:
float m_fov = 45.0f;
float m_width = 3840;
float m_height = 2160;
float m_zNear = 0.1f;
float m_zFar = 100.0f;
Из этого я могу вычислить ширину / высоту моего окна в z-near & z-far:
float zNearHeight = tan(m_fov) * m_zNear * 2;
float zNearWidth = zNearHeight * m_width / m_height;
float zFarHeight = tan(m_fov) * m_zFar * 2;
float zFarWidth = zFarHeight * m_width / m_height;
Теперь я могу создать свой вид & матрицы проекции:
glm::mat4 projectionMatrix = glm::perspective(glm::radians(m_fov), m_width / m_height, m_zNear, m_zFar);
glm::mat4 viewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -m_zNear));
Теперь я ожидаю, что мой прямоугольник заполнит окно:
glm::mat4 identity = glm::mat4(1.0f);
glm::mat4 rectangleModelMatrix = glm::scale(identity, glm::vec3(zNearWidth, zNearHeight, 1));
Но при этом мой прямоугольник слишком большой. Что я пропустил?
РЕШЕНИЕ: как указывал @ Rabbid76, проблема заключалась в вычислении моего размера z-near, который должен быть:
float m_zNearHeight = tan(glm::radians(m_fov) / 2.0f) * m_zNear * 2.0f;
float m_zNearWidth = m_zNearHeight * m_width / m_height;
Также я Теперь нужно указать координаты моего объекта в нормализованном пространстве вида ([-0,5, 0,5]), а не в пространстве устройства ([-1, 1]). Таким образом, мои вершины теперь должны быть:
GLfloat vertices[] = {
-0.5f, 0.5f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, // Bottom-right
-0.5f, -0.5f, 0.0f, // Bottom-left
};