Mai*_*ein 4 c++ opengl glm-math
我目前正在尝试创建一个 2d 游戏,但令我感到有点震惊的是,我找不到任何转换,例如旋转、缩放、vec2 的翻译。
例如,据我所知,rotate 仅适用于 mat4x4,并且 mat4x4 只能乘以 vec4。
这有什么理由吗?
我想在 CPU 上计算我的顶点
std::vector<glm::mat2> m;
Run Code Online (Sandbox Code Playgroud)
收集所有矩阵、生成顶点、填充 GPU 缓冲区,然后在一次绘制调用中绘制所有内容。
我该如何在 glm 中做到这一点?只使用 mat4 然后忽略 z 和 w 分量?
您应该理解的一件事是您不能忽略 z 分量,更不用说 w 分量了。这取决于你想如何看待问题。问题是您想使用 mat2 和 vec2 进行 2D,但可惜它并不像您想象的那么简单。您正在使用 OpenGL,并且可能也使用着色器。您需要至少使用 a glm::mat3,或更好:mat4。这样做的原因是,虽然你想要一切都是 2D 的,但它必须以 3D 的方式完成。2D 实际上只是 3D,z 缓冲区为 1,剪辑窗格相对于窗口大小是静态的。
所以,我的建议是这样的:
对于您的模型矩阵,您可以将其作为glm::mat4包含所有数据的矩阵,即使您不打算使用它。一致性在这里很重要,尤其是对于转换而言。
不要忽略glm::mat4;中的 z 和 w 分量。它们很重要,因为它们的价值观决定了它们在屏幕上的位置。OpenGL 需要知道某个值在 z 平面中的位置。并且对于矩阵乘法,需要齐次坐标,因此w分量也很重要。换句话说,你实际上被困在了glm::mat4。
为了让glm::mat4你得到转变应该
#include <glm/gtc/matrix_transform.hpp>
单独对待你的精灵;就像有一个Sprite班级,然后将他们分组到该班级之外。不要递归地进行分组,因为这会导致代码混乱。应该在每个 Sprite 的基础上生成顶点;不用担心优化,因为 OpenGL 会为你处理好这个问题,更不用说 C++ 方面的编译器了。你很快就会意识到,通过分解这个问题,你可以得到类似的东西
std::vector<Sprite*> sprites;
for (const auto& : i)
i->init();
// etc...
for (const auto& : i)
i->render();
Run Code Online (Sandbox Code Playgroud)
关于着色器,您不应该将它们真正放在 Sprite 类中。有一个资源加载器,并且只需让每个 Sprite 类从该加载器检索着色器即可。
最重要的是:记住转换的顺序!
关于精灵的变换,您可以做的是使用glm::vec3精灵位置,将 z 分量设置为 0。然后,您可以通过简单地使用需要 x 和 y 值的函数来移动精灵。使用 将这些值输入模型矩阵glm::translate(..)。关于旋转,您glm::rotate()只需使用获取旋转角度的函数即可。始终在 Z 窗格上旋转,因此它应该与此类似:
modelMatrix = glm::rotate(modelMatrix, glm::radians(angle), glm::vec3(0.f, 0.f, 1.f));
Run Code Online (Sandbox Code Playgroud)
至于缩放,同样是一个setScale()接受 x 和 y 两个值的合适函数。将 z 分量设置为 1 以防止 Sprite 在 z 方向上缩放。将值输入glm::scale如下:
modelMatrix = glm::scale(modelMatrix, glm::vec3(scale));
Run Code Online (Sandbox Code Playgroud)
请记住,存储矩阵几乎没有什么好处,因为它们只是数字;它们并不表明您真正想用它们做什么。类最好Sprite封装一个矩阵,以便清楚它们代表什么。
不客气!