C++ 尝试在三维空间中旋转二维形状时出现问题

C++ 尝试在三维空间中旋转二维形状时出现问题,c++,math,opengl,3d,glm-math,C++,Math,Opengl,3d,Glm Math,我正在开发一个批渲染器,但在为二维形状(如矩形或三角形)实现旋转功能时遇到了问题。我使用Vertex*(下面的struct Vertex代码)来存储位置和颜色值,这非常有效,直到我开始旋转 struct Vertex { glm::vec3 position; glm::vec4 color; }; 我尝试制作一个mat4并相应地使用相应的旋转函数,在着色器中设置模型视图投影时效果很好,但是将数据转换为顶点不起作用,而且非常缓慢。因此,我想我使用了一些我在网上找到的数学知识,但

我正在开发一个批渲染器,但在为二维形状(如矩形或三角形)实现旋转功能时遇到了问题。我使用Vertex*(下面的struct Vertex代码)来存储位置和颜色值,这非常有效,直到我开始旋转

struct Vertex
{
    glm::vec3 position;
    glm::vec4 color;
};
我尝试制作一个mat4并相应地使用相应的旋转函数,在着色器中设置模型视图投影时效果很好,但是将数据转换为顶点不起作用,而且非常缓慢。因此,我想我使用了一些我在网上找到的数学知识,但我画的正方形有时会被拉伸成长方形,而且位置不正确。我现在花了很多时间,尝试了不同的东西,但没有任何效果。这就是为什么我希望有人能在我的代码中找到一个明显的bug,或者指导我找到一个好的源代码,在那里我可以阅读关于这个主题的内容(我发现的内容要么与我的目的无关,要么难以理解)

以下是我的总结代码,我尽量使其简短:

void rotateX(float angle) 
{
    yr = yr * cos(angle) - zr * sin(angle);
    zr = zr * cos(angle) + yr * sin(angle);
}

void rotateY(float angle)
{
    xr = xr * cos(angle) - zr * sin(angle);
    zr = zr * cos(angle) + xr * sin(angle);
}

void rotateZ(float angle)
{
    xr = xr * cos(angle) - yr * sin(angle);
    yr = yr * cos(angle) + xr * sin(angle);
}

std::array<Vertex, 4> createQuad(glm::vec3 pos, glm::vec3 rotation, glm::vec4 rgba)
{
    float xr = 1.0f;
    float yr = 1.0f;
    float zr = 1.0f;

    rotateX(rotation.x);
    rotateY(rotation.y);
    rotateZ(rotation.z);

    Vertex v0;
    v0.position = glm::vec3(pos.x,      pos.y + yr, pos.z);
    v0.color = rgba;

    Vertex v1;
    v1.position = glm::vec3(pos.x + xr, pos.y + yr, pos.z);
    v1.color = rgba;

    Vertex v2;
    v2.position = glm::vec3(pos.x + xr, pos.y, pos.z + zr);
    v2.color = rgba;

    Vertex v3;
    v3.position = glm::vec3(pos.x,      pos.y, pos.z + zr);
    v3.color = rgba;

    return { v0, v1, v2, v3 };
}
void rotateX(浮动角度)
{
yr=yr*cos(角度)-zr*sin(角度);
zr=zr*cos(角)+yr*sin(角);
}
空隙旋转(浮动角度)
{
xr=xr*cos(角度)-zr*sin(角度);
zr=zr*cos(角度)+xr*sin(角度);
}
空隙旋转(浮动角度)
{
xr=xr*cos(角度)-yr*sin(角度);
yr=yr*cos(角度)+xr*sin(角度);
}
std::array createQuad(glm::vec3位置、glm::vec3旋转、glm::vec4 rgba)
{
浮动xr=1.0f;
浮动yr=1.0f;
浮动zr=1.0f;
rotateX(rotation.x);
rotateY(rotation.y);
rotateZ(rotation.z);
顶点v0;
v0.position=glm::vec3(位置x、位置y+yr、位置z);
v0.color=rgba;
顶点v1;
v1.position=glm::vec3(位置x+xr,位置y+yr,位置z);
v1.color=rgba;
顶点v2;
v2.position=glm::vec3(位置x+xr、位置y、位置z+zr);
v2.color=rgba;
顶点v3;
v3.position=glm::vec3(pos.x,pos.y,pos.z+zr);
v3.color=rgba;
返回{v0,v1,v2,v3};
}
其他说明:

  • 当我删除rotate()和“+yr”时,代码运行良好。 我不能100%确定“+yr”,但我不知道如何绕y轴旋转
  • 使用“[]”访问mat4的元素并没有给我提供正确的值,而且由于某些原因,它确实很滞后。这就是为什么如果可能的话,我会尽量避免这种情况,并采用原始数学

  • 我现在要去睡觉了,真的很晚了,我头痛。。。希望我的问题不是太愚蠢,那样的话,我很抱歉打扰你。提前感谢您的帮助

    首先,更改
    rotate
    函数以接受向量作为参数,而不是将旋转应用于全局变量(或其他变量)

    然后,代替一个向量:

    r = {1, 1, 1}
    
    使用两种方法:

    r = {1, 0, 0}
    s = {0, 1, 0}
    
    旋转它们(使用相同的角度参数),然后构造正方形。(我不知道glm::vec3的语法,但这是一个简单的向量加法):


    您希望
    createQuad
    做什么?创建一个矩形?创建一个正方形?您希望创建的对象以
    pos
    为中心,还是将
    pos
    作为一个顶点?您是否有您提供的输入和所需输出的示例?“当我在着色器中设置模型视图投影时,效果很好,但将数据转换为顶点不起作用[…]”-为什么要这样做?在哪里应用投影矩阵?为什么不将向量乘以矩阵?@Beta,我希望createQuad在glm::vec3位置创建一个正方形。然后,我返回的四个“结构顶点”可以轻松添加到顶点*,我通过glBufferSubData将其提供给GPU。现在,我不在乎它是围绕中心旋转还是在一个顶点旋转。输入时,x、y或z轴的角度大多为45度,但将正方形拉伸为矩形。此外,绕y轴旋转根本不起作用。我想要的输出是一个绕相应轴旋转的正方形。@rabbi76我想要从矩阵中获取数据,这样我就可以用它创建一个“结构顶点”。这样,我就可以将它们添加到我的顶点*并轻松地将它们发送到GPU。我在着色器中设置了投影矩阵和视图矩阵,因为它们不会更改。后来我想改变顶点的位置,但仍然是批处理的,这就是为什么我直接将它们交给GPU的原因。为了更改之前的位置,我更改了着色器中的矩阵,并执行了另一个绘制调用,这让我可以延迟。@KnightCode我不知道“我想从矩阵中获取数据,以便可以使用它创建“结构顶点”是什么意思。”。为什么要在CPU而不是GPU上进行模型转换?无论如何,在设置投影矩阵时,您是否注意到纵横比(矩形视口)。谢谢@Beta的帮助,我对旋转的理解和我的实现是有缺陷的。你的回答很清楚这一点!我还混合了度和弧度,当给这个函数它的旋转变量。希望你有一个愉快的一天!
    Vertex v0 = pos;
    
    Vertex v1 = pos + r;
    
    Vertex v2 = pos + r + s;
    
    Vertex v3 = pos + s;