opengl 在GLM中旋转、缩放和平移2D点

b1zrtrql  于 2022-11-23  发布在  其他
关注(0)|答案(2)|浏览(318)

我目前正在尝试创建一个2D游戏,我有点震惊,我找不到任何像旋转,缩放,翻译为vec2的转换。
例如,据我所知,rotate只适用于mat4x4,而mat4x4只能乘以vec4。
有什么理由吗?
我想在CPU上计算顶点

std::vector<glm::mat2> m;

收集所有矩阵,生成顶点,填充GPU缓冲区,然后在一个绘制调用中绘制所有内容。
在glm中我该怎么做呢?只是使用mat4然后忽略z和w分量?

fhg3lkii

fhg3lkii1#

有一点你应该明白,你不能忽略z分量,更不用说w分量了。这取决于你想如何看待这个问题。问题是你想用mat 2和vec 2来做2D,但唉,这并不像你想的那么简单。你正在使用OpenGL,而且可能也在使用着色器。你至少需要使用glm::mat3,或者更好:mat4。其原因是,尽管您希望所有内容都以2D形式呈现,但必须以3D形式呈现。2D实际上只是3D,z缓冲区为1,剪辑窗格相对于窗口大小而言是静态的。
所以,我的建议是:
1.对于您的模型矩阵,即使您不打算使用它,您也可以将其作为包含所有数据的glm::mat4
1.不要忽略glm::mat4中的z和w分量;它们之所以重要,是因为它们的值决定了它们在屏幕上的位置。OpenGL需要知道值在z平面的位置。对于矩阵乘法,需要齐次坐标,因此w分量也很重要。换句话说,您实际上只能使用glm::mat4
1.要获取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的转换,您可以为sprite位置设置一个glm::vec3,将z分量设置为0。然后,您可以简单地通过一个需要x和y值的函数来移动sprite。使用glm::translate(..)将这些值输入模型矩阵。关于旋转,您使用glm::rotate(),并且只具有获取旋转Angular 的函数。始终在Z窗格上旋转因此,它应该类似于:

modelMatrix = glm::rotate(modelMatrix, glm::radians(angle), glm::vec3(0.f, 0.f, 1.f));

至于缩放,同样是一个合适的setScale()函数,它接受x和y的两个值。将z分量设置为1,以防止Sprite在z方向上缩放。将值输入glm::scale,如下所示:

modelMatrix = glm::scale(modelMatrix, glm::vec3(scale));

请记住,存储矩阵没有什么好处,因为它们只是数字;它们并不表示您真正想用它们做什么。Sprite类最好封装一个矩阵,以便清楚地表示它们的含义。
不客气!

相关问题