【问题标题】:2D Geometry Distorts When Translating平移时 2D 几何变形
【发布时间】:2014-06-27 16:23:33
【问题描述】:

我有一个项目用于在 OSX 上学习 OpenGL,我找到了它here。我已对其进行了修改,以便我可以开始在简单的 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* 函数都会执行指示的矩阵数学运算,并将结果放入传递的第一个参数中。我必须假设它们都正常工作,因为它们与运行良好的原始 Apple 示例项目没有任何变化。

mtxLoadPerspective() 函数的签名是:

void mtxLoadPerspective(float* mtx, float fov, float aspect, float nearZ, float farZ)

[*] 的两行代码基于对其他站点上类似问题的回答,其中指令是根据纵横比在 X 轴上缩放、旋转然后缩小。

我认为纵横比是问题的核心是否正确?是否有人知道可以指导我的示例代码?

编辑:着色器使用列主要数学作为位置

gl_Position = modelViewProjectionMatrix * inPosition;

正如answer所指出的那样。

编辑:澄清mtx* 功能。

mtxLoadPerspective() 像这样转换 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];
}

【问题讨论】:

  • 如果不看那些mtx*() 函数是如何实现的,就很难说清楚。例如,mtxLoadPerspective() 确实以度为单位,而不是弧度?我真的很惊讶你看到任何东西,因为你在 z 方向上有 -500 的平移,但你的远平面只有 100 远。我的主要嫌疑人是乘法顺序或转置问题。但这一切都取决于mtx*() 函数是对行主矩阵还是列主矩阵进行操作,以及mtxMultiply() 相乘的顺序。
  • 远平面应该是 1000,这肯定是我错误地调整了一些东西,但是是的,奇怪的是我仍然看到一些东西。 mtx* 函数被列为主要列。

标签: macos opengl


【解决方案1】:

嗯,

我终于让代码工作了,但我不清楚为什么。

总的来说,我将恒等矩阵加载到viewmodelprojection

x、y、z 缩放应用于model 矩阵。

然后将 x、y、z 旋转应用于model 矩阵。

x 和 y 转换也适用于 model

然而,z 平移应用于view 矩阵(虽然我确实理解将相机移回以查看几何图形的概念,但我只是不明白为什么将 x 和 y 平移应用于@ 987654328@矩阵什么都不做)。

然后我做乘法model * view,这进入modelView矩阵。

然后执行modelView * projection 并将此产品发送到着色器。

如果有人能对此发表评论并阐明这一点,我将不胜感激,但与此同时,我会犯错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 2016-05-18
    相关资源
    最近更新 更多