我目前正在尝试创建一个2D游戏,我有点震惊,我找不到任何像旋转,缩放,翻译为vec2的转换。例如,据我所知,rotate只适用于mat4x4,而mat4x4只能乘以vec4。有什么理由吗?我想在CPU上计算顶点
std::vector<glm::mat2> m;
收集所有矩阵,生成顶点,填充GPU缓冲区,然后在一个绘制调用中绘制所有内容。在glm中我该怎么做呢?只是使用mat4然后忽略z和w分量?
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++方面的编译器了。你很快就会意识到,通过解决这个问题,你可以得到类似这样的东西
glm::mat3
mat4
glm::mat4
#include <glm/gtc/matrix_transform.hpp>
Sprite
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窗格上旋转因此,它应该类似于:
glm::vec3
glm::translate(..)
glm::rotate()
modelMatrix = glm::rotate(modelMatrix, glm::radians(angle), glm::vec3(0.f, 0.f, 1.f));
至于缩放,同样是一个合适的setScale()函数,它接受x和y的两个值。将z分量设置为1,以防止Sprite在z方向上缩放。将值输入glm::scale,如下所示:
setScale()
glm::scale
modelMatrix = glm::scale(modelMatrix, glm::vec3(scale));
请记住,存储矩阵没有什么好处,因为它们只是数字;它们并不表示您真正想用它们做什么。Sprite类最好封装一个矩阵,以便清楚地表示它们的含义。不客气!
axr492tv2#
看来我还不够努力:从glm/gtx/matrix_transform_2d.hpp中删除GLM_GTX_matrix_transform_2d。
glm/gtx/matrix_transform_2d.hpp
GLM_GTX_matrix_transform_2d
2条答案
按热度按时间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++方面的编译器了。你很快就会意识到,通过解决这个问题,你可以得到类似这样的东西至于着色器,你不应该把它们放在Sprite类中,而是要有一个资源加载器,然后让每个Sprite类从那个加载器中检索着色器。
最重要的是:记住变换的顺序!
关于sprite的转换,您可以为sprite位置设置一个
glm::vec3
,将z分量设置为0。然后,您可以简单地通过一个需要x和y值的函数来移动sprite。使用glm::translate(..)
将这些值输入模型矩阵。关于旋转,您使用glm::rotate()
,并且只具有获取旋转Angular 的函数。始终在Z窗格上旋转因此,它应该类似于:至于缩放,同样是一个合适的
setScale()
函数,它接受x和y的两个值。将z分量设置为1,以防止Sprite在z方向上缩放。将值输入glm::scale
,如下所示:请记住,存储矩阵没有什么好处,因为它们只是数字;它们并不表示您真正想用它们做什么。
Sprite
类最好封装一个矩阵,以便清楚地表示它们的含义。不客气!
axr492tv2#
看来我还不够努力:
从
glm/gtx/matrix_transform_2d.hpp
中删除GLM_GTX_matrix_transform_2d
。