在GLM中旋转,缩放和翻译2d点

时间:2015-12-16 03:30:42

标签: c++ opengl glm-math

我正在尝试创建一个2D游戏,我有点震惊,我找不到任何转换,如旋转,缩放,转换为vec2。

例如据我所知,旋转仅适用于mat4x4,而mat4x4只能乘以vec4。

有什么理由吗?

我想在CPU上计算我的顶点

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

收集所有矩阵,生成顶点,填充GPU缓冲区,然后在一次绘制调用中绘制所有内容。

我将如何在glm中执行此操作?只需使用mat4然后忽略z和w组件?

2 个答案:

答案 0 :(得分:3)

您应该理解的一件事是,您不能忽略z组件,更不用说w组件了。这取决于您希望如何查看问题。问题是你想使用mat2和vec2来制作2D,但是它并不像你想象的那么简单。您正在使用OpenGL,并且可能也是使用着色器。您需要至少使用glm::mat3或更好:mat4。这样做的原因是,虽然你想要2D中的所有东西,但它必须用3D来完成。 2D实际上只是3D,z缓冲区为1,剪辑窗格相对于窗口大小只是静态的。

所以,我建议的是:

  1. 对于您的模型矩阵,您将其作为glm::mat4包含所有数据,即使您不打算使用它。一致性在这里很重要,特别是对于转换。

  2. 不要忽略glm::mat4中的z和w组件;它们很重要,因为它们的价值决定了它们在屏幕上的位置。 OpenGL需要知道z平面中的值是什么。对于矩阵乘法,需要同质坐标,因此w分量也很重要。换句话说,您几乎坚持使用glm::mat4

  3. 要获得glm::mat4的转换,您应该

    #include <glm/gtc/matrix_transform.hpp>

  4. 分开对待你的精灵;如同拥有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)

似乎我看起来不够努力http://glm.g-truc.net/0.9.7/api/a00213.html

相关问题