Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.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
Macos 二维几何体在平移时会扭曲_Macos_Opengl - Fatal编程技术网

Macos 二维几何体在平移时会扭曲

Macos 二维几何体在平移时会扭曲,macos,opengl,Macos,Opengl,我有一个在OSX上学习OpenGL的项目,我找到了它。我将其修改为,这样我就可以开始在简单的2D几何体上使用自己的纹理 我遇到了一个我知道经常被问到的问题,但我找不到适合我的解决方案 我只是想平移几何体,使其向左、向右、向上、向下移动,但当我这样做时,它的形状会扭曲 像这样: 它应该如下所示,但只是在X轴上移动: 我使用的代码是: static GLfloat modelView[16]; static GLfloat projection[16]; static GLfloat objec

我有一个在OSX上学习OpenGL的项目,我找到了它。我将其修改为,这样我就可以开始在简单的2D几何体上使用自己的纹理

我遇到了一个我知道经常被问到的问题,但我找不到适合我的解决方案

我只是想平移几何体,使其向左、向右、向上、向下移动,但当我这样做时,它的形状会扭曲

像这样:

它应该如下所示,但只是在X轴上移动:

我使用的代码是:

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*函数列为主列。