Macos 二维几何体在平移时会扭曲
我有一个在OSX上学习OpenGL的项目,我找到了它。我将其修改为,这样我就可以开始在简单的2D几何体上使用自己的纹理 我遇到了一个我知道经常被问到的问题,但我找不到适合我的解决方案 我只是想平移几何体,使其向左、向右、向上、向下移动,但当我这样做时,它的形状会扭曲 像这样: 它应该如下所示,但只是在X轴上移动: 我使用的代码是:Macos 二维几何体在平移时会扭曲,macos,opengl,Macos,Opengl,我有一个在OSX上学习OpenGL的项目,我找到了它。我将其修改为,这样我就可以开始在简单的2D几何体上使用自己的纹理 我遇到了一个我知道经常被问到的问题,但我找不到适合我的解决方案 我只是想平移几何体,使其向左、向右、向上、向下移动,但当我这样做时,它的形状会扭曲 像这样: 它应该如下所示,但只是在X轴上移动: 我使用的代码是: static GLfloat modelView[16]; static GLfloat projection[16]; static GLfloat objec
static GLfloat modelView[16];
static GLfloat projection[16];
static GLfloat objectMvp[16];
static GLfloat model[16];
static GLfloat view[16];
mtxLoadIdentity(model);
mtxLoadIdentity(view);
mtxLoadIdentity(modelView);
mtxLoadIdentity(projection);
//load the desired projection matrix into projection var
mtxLoadPerspective(projection, 90, m_viewAspect, 0.1, 100);
//m_viewAspect is updated every time the window changes shape
//and is window.width/window.height
mtxTranslateApply(model, 0.3, 0, -500);
mtxScaleApply(model, m_viewAspect, 1, 1); //[*]
mtxRotateXApply(model, 0);
mtxRotateYApply(model, 0);
mtxRotateZApply(model, 0);
mtxScaleApply(model, 1/m_viewAspect, 1, 1); //[*]
mtxMultiply(modelView, view, model);
mtxMultiply(objectMvp, projection, modelView);
//and send objectMvp to the shader for rendering…
glUniformMatrix4fv(m_UniformIdx, 1, GL_FALSE, objectMvp);
所有的mtx*
函数都会执行指定的矩阵数学运算,并将结果放入传递的第一个参数中。我必须假设它们都能正常工作,因为它们与最初的苹果示例项目没有什么不同,该项目运行良好
mtxloadprospective()
函数的签名是:
void mtxLoadPerspective(float* mtx, float fov, float aspect, float nearZ, float farZ)
这两行代码基于对其他站点上类似问题的回答,这些站点上的说明是根据纵横比在X轴上缩放,进行旋转,然后缩小
我认为纵横比是问题的核心,对吗?有没有人知道的示例代码可以指导我
编辑:着色器对位置使用列主数学
gl_Position = modelViewProjectionMatrix * inPosition;
如此所示
编辑:澄清mtx*
功能
mtxloadprospective()
如下转换FOV:
float f = 1.0f / tanf( (fov * (M_PI/180)) / 2.0f);
翻译功能是:
void mtxTranslateApply(float* mtx, float xTrans, float yTrans, float zTrans)
{
mtx[12] += mtx[0]*xTrans + mtx[4]*yTrans + mtx[ 8]*zTrans;
mtx[13] += mtx[1]*xTrans + mtx[5]*yTrans + mtx[ 9]*zTrans;
mtx[14] += mtx[2]*xTrans + mtx[6]*yTrans + mtx[10]*zTrans;
}
其他功能包括:
void mtxMultiply(float* ret, const float* lhs, const float* rhs)
{
ret[ 0] = lhs[ 0]*rhs[ 0] + lhs[ 4]*rhs[ 1] + lhs[ 8]*rhs[ 2] + lhs[12]*rhs[ 3];
ret[ 1] = lhs[ 1]*rhs[ 0] + lhs[ 5]*rhs[ 1] + lhs[ 9]*rhs[ 2] + lhs[13]*rhs[ 3];
ret[ 2] = lhs[ 2]*rhs[ 0] + lhs[ 6]*rhs[ 1] + lhs[10]*rhs[ 2] + lhs[14]*rhs[ 3];
ret[ 3] = lhs[ 3]*rhs[ 0] + lhs[ 7]*rhs[ 1] + lhs[11]*rhs[ 2] + lhs[15]*rhs[ 3];
ret[ 4] = lhs[ 0]*rhs[ 4] + lhs[ 4]*rhs[ 5] + lhs[ 8]*rhs[ 6] + lhs[12]*rhs[ 7];
ret[ 5] = lhs[ 1]*rhs[ 4] + lhs[ 5]*rhs[ 5] + lhs[ 9]*rhs[ 6] + lhs[13]*rhs[ 7];
ret[ 6] = lhs[ 2]*rhs[ 4] + lhs[ 6]*rhs[ 5] + lhs[10]*rhs[ 6] + lhs[14]*rhs[ 7];
ret[ 7] = lhs[ 3]*rhs[ 4] + lhs[ 7]*rhs[ 5] + lhs[11]*rhs[ 6] + lhs[15]*rhs[ 7];
ret[ 8] = lhs[ 0]*rhs[ 8] + lhs[ 4]*rhs[ 9] + lhs[ 8]*rhs[10] + lhs[12]*rhs[11];
ret[ 9] = lhs[ 1]*rhs[ 8] + lhs[ 5]*rhs[ 9] + lhs[ 9]*rhs[10] + lhs[13]*rhs[11];
ret[10] = lhs[ 2]*rhs[ 8] + lhs[ 6]*rhs[ 9] + lhs[10]*rhs[10] + lhs[14]*rhs[11];
ret[11] = lhs[ 3]*rhs[ 8] + lhs[ 7]*rhs[ 9] + lhs[11]*rhs[10] + lhs[15]*rhs[11];
ret[12] = lhs[ 0]*rhs[12] + lhs[ 4]*rhs[13] + lhs[ 8]*rhs[14] + lhs[12]*rhs[15];
ret[13] = lhs[ 1]*rhs[12] + lhs[ 5]*rhs[13] + lhs[ 9]*rhs[14] + lhs[13]*rhs[15];
ret[14] = lhs[ 2]*rhs[12] + lhs[ 6]*rhs[13] + lhs[10]*rhs[14] + lhs[14]*rhs[15];
ret[15] = lhs[ 3]*rhs[12] + lhs[ 7]*rhs[13] + lhs[11]*rhs[14] + lhs[15]*rhs[15];
}
void mtxScaleApply(float* mtx, float xScale, float yScale, float zScale)
{
mtx[ 0] *= xScale;
mtx[ 4] *= yScale;
mtx[ 8] *= zScale;
mtx[ 1] *= xScale;
mtx[ 5] *= yScale;
mtx[ 9] *= zScale;
mtx[ 2] *= xScale;
mtx[ 6] *= yScale;
mtx[10] *= zScale;
mtx[ 3] *= xScale;
mtx[ 7] *= yScale;
mtx[11] *= xScale;
}
void mtxRotateXMatrix(float* mtx, float rad)
{
float cosrad = cosf(rad);
float sinrad = sinf(rad);
float mtx01 = mtx[ 1];
float mtx05 = mtx[ 5];
float mtx09 = mtx[ 9];
float mtx13 = mtx[13];
mtx[ 1] = cosrad*mtx01 - sinrad*mtx[ 2];
mtx[ 2] = sinrad*mtx01 + cosrad*mtx[ 2];
mtx[ 5] = cosrad*mtx05 - sinrad*mtx[ 6];
mtx[ 6] = sinrad*mtx05 + cosrad*mtx[ 6];
mtx[ 9] = cosrad*mtx09 - sinrad*mtx[10];
mtx[10] = sinrad*mtx09 + cosrad*mtx[10];
mtx[13] = cosrad*mtx13 - sinrad*mtx[14];
mtx[14] = sinrad*mtx13 + cosrad*mtx[14];
}
void mtxRotateYMatrix(float* mtx, float rad)
{
float cosrad = cosf(rad);
float sinrad = sinf(rad);
float mtx00 = mtx[ 0];
float mtx04 = mtx[ 4];
float mtx08 = mtx[ 8];
float mtx12 = mtx[12];
mtx[ 0] = cosrad*mtx00 - sinrad*mtx[ 2];
mtx[ 2] = sinrad*mtx00 + cosrad*mtx[ 2];
mtx[ 4] = cosrad*mtx04 - sinrad*mtx[ 6];
mtx[ 6] = sinrad*mtx04 + cosrad*mtx[ 6];
mtx[ 8] = cosrad*mtx08 - sinrad*mtx[10];
mtx[10] = sinrad*mtx08 + cosrad*mtx[10];
mtx[12] = cosrad*mtx12 - sinrad*mtx[14];
mtx[14] = sinrad*mtx12 + cosrad*mtx[14];
}
void mtxRotateZMatrix(float* mtx, float rad)
{
float cosrad = cosf(rad);
float sinrad = sinf(rad);
float mtx00 = mtx[ 0];
float mtx04 = mtx[ 4];
float mtx08 = mtx[ 8];
float mtx12 = mtx[12];
mtx[ 0] = cosrad*mtx00 - sinrad*mtx[ 1];
mtx[ 1] = sinrad*mtx00 + cosrad*mtx[ 1];
mtx[ 4] = cosrad*mtx04 - sinrad*mtx[ 5];
mtx[ 5] = sinrad*mtx04 + cosrad*mtx[ 5];
mtx[ 8] = cosrad*mtx08 - sinrad*mtx[ 9];
mtx[ 9] = sinrad*mtx08 + cosrad*mtx[ 9];
mtx[12] = cosrad*mtx12 - sinrad*mtx[13];
mtx[13] = sinrad*mtx12 + cosrad*mtx[13];
}
那么
我终于让代码工作了,但我不清楚为什么
总体而言,我将标识矩阵加载到视图
、模型
和投影
x、y、z缩放应用于模型
矩阵
然后将x、y、z旋转应用于模型
矩阵
x和y转换也应用于模型
但是,z平移应用于视图
矩阵(虽然我确实理解将相机移回以查看几何体的概念,但我不明白为什么将x和y平移应用于视图
矩阵不会产生任何效果)
然后我进行乘法model*视图
,这将进入modelView
矩阵
然后执行modelView*投影
,该产品将被发送到着色器
如果有人能对此发表评论并加以说明,我将不胜感激,但在此期间,我将大错特错。如果没有看到那些
mtx*()
函数是如何实现的,那就很难说了。例如,mtxloadprospective()
的角度是度,而不是弧度?事实上,我很惊讶你能看到任何东西,因为你在z方向上有一个-500的平移,但是你的远平面只有100远。我的主要怀疑是乘法顺序或换位的问题。但这一切都取决于mtx*()
函数是否使用行主矩阵或列主矩阵,以及mtxMultiply()
乘法的顺序。远平面应该是1000,这一定是我错误地调整的,但是的,奇怪的是我仍然看到了一些东西。mtx*函数列为主列。