C++ 尝试在三维空间中旋转二维形状时出现问题
我正在开发一个批渲染器,但在为二维形状(如矩形或三角形)实现旋转功能时遇到了问题。我使用Vertex*(下面的struct Vertex代码)来存储位置和颜色值,这非常有效,直到我开始旋转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并相应地使用相应的旋转函数,在着色器中设置模型视图投影时效果很好,但是将数据转换为顶点不起作用,而且非常缓慢。因此,我想我使用了一些我在网上找到的数学知识,但
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
函数以接受向量作为参数,而不是将旋转应用于全局变量(或其他变量)
然后,代替一个向量:
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;