【发布时间】:2020-04-16 13:22:50
【问题描述】:
我正在尝试理解 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
};
【问题讨论】:
标签: c++ opengl projection glm-math frustum