Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何正确使用opengl转换的矩阵进行数学运算?_C++_Opengl_Math_Matrix - Fatal编程技术网

C++ 如何正确使用opengl转换的矩阵进行数学运算?

C++ 如何正确使用opengl转换的矩阵进行数学运算?,c++,opengl,math,matrix,C++,Opengl,Math,Matrix,我真的很困惑矩阵是如何工作的,以及如何使用它们。作为一个测试,我试着让一个矩形在向一个角移动时逆时针旋转,而这个矩形的大小是它的一半。除了旋转,基本上一切都不工作 如果您想知道,我没有使用GLM,也不想使用GLM。我觉得我需要自己尝试一下,但现在我真的被卡住了。我尝试重新安排如何进行转换,但得到的结果是随机的 这是main.cpp中的代码,它是一个自定义游戏引擎,因此这里只是相关部分 Matrix4 transform = Matrix4(); // the matrix float d = 5

我真的很困惑矩阵是如何工作的,以及如何使用它们。作为一个测试,我试着让一个矩形在向一个角移动时逆时针旋转,而这个矩形的大小是它的一半。除了旋转,基本上一切都不工作

如果您想知道,我没有使用GLM,也不想使用GLM。我觉得我需要自己尝试一下,但现在我真的被卡住了。我尝试重新安排如何进行转换,但得到的结果是随机的

这是main.cpp中的代码,它是一个自定义游戏引擎,因此这里只是相关部分

Matrix4 transform = Matrix4(); // the matrix
float d = 5, g = 1;
void OnUserUpdate() override { // Called once every frame
    transform.Translate(Vector3(d * DeltaTime, d * DeltaTime, 0.0f));
    transform.Rotate(Vector3(0.0f, 0.0f, 1.0f), ToRadians(g));
    transform.Scale(Vector3(0.5f, 0.5f, 0.5f));

    g+=0.01;

    Shaders.SetMat4(shader, "transform", transform);
}
这是完整的矩阵类。向量3就是浮动的x,y,z。只有一个构造函数

template <typename Number> float ToRadians(Number deg) {
return deg * PI / 180;
}

struct Matrix4 {
private:
Matrix4& identity() {
    m[0] = m[5] = m[10] = m[15] = 1.0f;
    m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0.0f;
    return* this;
}
public:
float m[16];
Matrix4() {
    identity();
}

Matrix4(const float src[16]) {
    Set(src);
}

void Set(const float src[16]) {
    for (int i = 0; i < 16; i++) {
        m[i] = src[i];
    }
}

void Projection(float fov, float aspectratio, float nearpane, float farpane) {

}

void Translate(Vector3 v) {
    float x = v.x; float y = v.y; float z = v.y;
    m[0] += m[3] * x;   m[4] += m[7] * x;   m[8] += m[11] * x;   m[12] += m[15] * x;
    m[1] += m[3] * y;   m[5] += m[7] * y;   m[9] += m[11] * y;   m[13] += m[15] * y;
    m[2] += m[3] * z;   m[6] += m[7] * z;   m[10] += m[11] * z;   m[14] += m[15] * z;
}

void Rotate(Vector3 axis, float deg) {
    m[0] = cosf(deg)+axis.x*axis.x*(1-cosf(deg));
    m[1] = axis.y*axis.x*(1 - cosf(deg)) + axis.z*sinf(deg);
    m[2] = axis.z*axis.x*(1 - cosf(deg)) - axis.y*sinf(deg);
    m[4] = axis.x*axis.y*(1 - cosf(deg)) - axis.z*sinf(deg);
    m[5] = cosf(deg)+axis.y*axis.y*(1-cosf(deg));
    m[6] = axis.z*axis.y*(1 - cosf(deg)) + axis.x*sinf(deg);
    m[8] = axis.x*axis.z*(1 - cosf(deg)) + axis.y*sinf(deg);
    m[9] = axis.y*axis.z*(1 - cosf(deg)) - axis.x*sinf(deg);
    m[10] = cosf(deg) + axis.z*axis.z*(1 - cosf(deg));;
    m[15] = 1;
}

void Scale(Vector3 v) {
    float x = v.x; float y = v.y; float z = v.y;
    m[0] *= x;   m[4] *= x;   m[8] *= x;   m[12] *= x;
    m[1] *= y;   m[5] *= y;   m[9] *= y;   m[13] *= y;
    m[2] *= z;   m[6] *= z;   m[10] *= z;   m[14] *= z;
}
};
模板浮动半径(度数){
返回度*PI/180;
}
结构矩阵x4{
私人:
Matrix4&identity(){
m[0]=m[5]=m[10]=m[15]=1.0f;
m[1]=m[2]=m[3]=m[4]=m[6]=m[7]=m[8]=m[9]=m[11]=m[12]=m[13]=m[14]=0.0f;
归还*这个;
}
公众:
浮动m[16];
Matrix4(){
身份();
}
Matrix4(常量浮点src[16]){
Set(src);
}
无效集(常量浮点src[16]){
对于(int i=0;i<16;i++){
m[i]=src[i];
}
}
无效投影(浮动视野、浮动纵横比、浮动近窗格、浮动远窗格){
}
无效平移(矢量3 v){
浮动x=v.x;浮动y=v.y;浮动z=v.y;
m[0]+=m[3]*x;m[4]+=m[7]*x;m[8]+=m[11]*x;m[12]+=m[15]*x;
m[1]+=m[3]*y;m[5]+=m[7]*y;m[9]+=m[11]*y;m[13]+=m[15]*y;
m[2]+=m[3]*z;m[6]+=m[7]*z;m[10]+=m[11]*z;m[14]+=m[15]*z;
}
空心旋转(矢量3轴,浮动度){
m[0]=余弦(度)+轴x*轴x*(1-余弦(度));
m[1]=轴y*轴x*(1-余弦(度))+轴z*正弦(度);
m[2]=轴z*轴x*(1-余弦(度))-轴y*正弦(度);
m[4]=轴x*轴y*(1-余弦(度))-轴z*正弦(度);
m[5]=余弦(度)+y轴*y轴*(1-余弦(度));
m[6]=z轴*y轴*(1-余弦(度))+x轴*正弦(度);
m[8]=轴x*轴z*(1-余弦(度))+轴y*正弦(度);
m[9]=轴y*轴z*(1-余弦(度))-轴x*正弦(度);
m[10]=余弦(度)+轴z*轴z*(1-余弦(度));;
m[15]=1;
}
空隙比例(矢量3 v){
浮动x=v.x;浮动y=v.y;浮动z=v.y;
m[0]*=x;m[4]*=x;m[8]*=x;m[12]*=x;
m[1]*=y;m[5]*=y;m[9]*=y;m[13]*=y;
m[2]*=z;m[6]*=z;m[10]*=z;m[14]*=z;
}
};
正如我所说,我试图使一个矩形在向一个角移动时逆时针旋转,而这个矩形的大小是它的一半。我使用了一些资料来源,但老实说,我并没有完全理解一切

简化事情

创建3种方法,用于初始化缩放、平移和旋转矩阵:

struct Matrix4{
// ...
无效设置刻度(矢量3 v){
身份();
m[0]=v.x;m[5]=v.y;m[10]=v.z;
}
无效设置转换(矢量3 v){
身份();
m[12]=v.x;m[13]=v.y;m[14]=v.z;
}
无效设置旋转(矢量3 v,浮动弧度){
身份();
浮点数c=cosf(rad);
浮点数s=sinf(rad);
浮动x=v.x,y=v.x,z=v.z;
m[0]=x*x*(1.0f-c)+c;m[1]=x*y*(1.0f-c)-z*s;m[2]=x*z*(1.0f-c)+y*s;
m[4]=y*x*(1.0f-c)+z*s;m[5]=y*y*(1.0f-c)+c;m[6]=y*z*(1.0f-c)-x*s;
m[8]=z*x*(1.0f-c)-y*s;m[9]=z*y*(1.0f-c)+x*s;m[10]=z*z*(1.0f-c)+c;
}
// ...
}
进一步创建将矩阵乘以当前矩阵的方法:

struct Matrix4{
// ... 
无效乘法(常数矩阵4和b){
Matrix4 a;
a、 组(m);
对于(int k=0;k<4;++k){
对于(int j=0;j<4;++j){
m[k*4+j]=
a、 m[0*4+j]*b.m[k*4+0]+
a、 m[1*4+j]*b.m[k*4+1]+
a、 m[2*4+j]*b.m[k*4+2]+
a、 m[3*4+j]*b.m[k*4+3];
}
}
}
// ...
}
基于此方法,可以轻松实现缩放、平移和旋转现有矩阵的方法:

struct Matrix4{
// ... 
空隙比例(矢量3 v){
matrix4s;
s、 设置刻度(v);
倍增;
}
无效平移(矢量3 v){
matrix4t;
t、 SetTranslate(v);
乘(t);
}
空心旋转(矢量3轴,浮动弧度){
matrix4r;
r、 设置旋转(轴,弧度);
乘(r);
}
// ...
}
跑吧。之后,您可以尝试对这些方法进行优化,但您将有一个比较结果的工作基础


注意,在
变换中,旋转(向量3(0.0f,0.0f,1.0f),旋转半径(g))角度从度转换为辐射角度
g+=0.01
是向前迈出的一小步(以度为单位)。可能您应该将其更改为
g+=1.0
,以便在任何帧中都能看到明显的变化


最后,在进行转换之前,必须通过标识矩阵初始化调制解调器矩阵(
转换
)。否则,新的变换将在先前帧的变换之上进行。这将导致网格迅速缩小,并且平移到以下位置:

float g=0,t=0;
void OnUserUpdate()覆盖{
transform=Matrix4();
transform.Translate(向量3(t,t,0.0f));
变换.旋转(矢量3(0.0f,0.0f,1.0f),环面(g));
变换比例(矢量3(0.5f,0.5f,0.5f));
t+=0.1*DeltaTime;
g+=5;
SetMat4(着色器,“变换”,变换);
}

这同样适用于3d吗?是的,文章涵盖3d,保持阅读感觉更好,尽管还有一个问题:上次调用transform似乎覆盖了所有其他内容。因此,缩放会影响变换和旋转。Translate没有按预期工作,但我做了一些更改以使其工作
void Set