我正在尝试创建一个2D游戏,我有点震惊,我找不到任何转换,如旋转,缩放,转换为vec2。
例如据我所知,旋转仅适用于mat4x4,而mat4x4只能乘以vec4。
有什么理由吗?
我想在CPU上计算我的顶点
std::vector<glm::mat2> m;
收集所有矩阵,生成顶点,填充GPU缓冲区,然后在一次绘制调用中绘制所有内容。
我将如何在glm中执行此操作?只需使用mat4然后忽略z和w组件?
答案 0 :(得分:3)
您应该理解的一件事是,您不能忽略z组件,更不用说w组件了。这取决于您希望如何查看问题。问题是你想使用mat2和vec2来制作2D,但是它并不像你想象的那么简单。您正在使用OpenGL,并且可能也是使用着色器。您需要至少使用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();
关于着色器,你不应该在Sprite类中真正拥有它们。拥有一个资源加载器,并让每个Sprite类从该加载器中检索着色器。
最重要的是:记住变换的顺序!
关于sprite的变换,你可以做的是为精灵位置设置glm::vec3
,将z分量设置为0.然后你可以通过简单地拥有一个想要x和y的函数来移动你的精灵。值。使用glm::translate(..)
将这些值输入模型矩阵。关于旋转,您使用glm::rotate()
并且只具有获得旋转角度的函数。 始终在Z-PANE上旋转因此它应该与此相似:
modelMatrix = glm::rotate(modelMatrix, glm::radians(angle), glm::vec3(0.f, 0.f, 1.f));
对于缩放,再次是一个合适的setScale()
函数,它接受x和y的两个值。将z组件设置为1以防止在z中缩放Sprite。将值输入glm::scale
,如下所示:
modelMatrix = glm::scale(modelMatrix, glm::vec3(scale));
请记住,存储矩阵几乎没有什么好处,因为它们只是数字;他们没有表明你真正想要用它们做什么。对于Sprite
类来说,封装矩阵以便明确它们的含义是更好的。
欢迎你!
答案 1 :(得分:0)