【问题标题】:OpenGL ES 2.0 setLookAtMOpenGL ES 2.0 setLookAtM
【发布时间】:2014-05-18 19:24:01
【问题描述】:

我遇到了 setLookAtM 函数的问题。我的目标是在像这样的立方体中创建一个立方体(是的,它是油漆:P):

所以基本上一切正常......几乎......我有一个较小的立方体,我有一个更大的立方体。 但是,有一个问题。我用 -1 到 1 的坐标创建了更大的坐标,现在我想升级它。使用比例 1.0f 我有这样的东西(内部立方体正在旋转):

这很好,但是现在...当我尝试缩放更大的立方体(使其看起来像在绘画中)时,图像变成黑色或白色(我猜这是因为“相机”看着白色立方体但我仍然不知道为什么我的内部立方体消失了:/我不明白我做错了什么。这是我的代码:

public void onDrawFrame(GL10 unused) {
    float[] scratch = new float[16];
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -5.0f, 0f, 0f, -1.0f, 0f, 1.0f, 0.0f);

    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

    mRoom.mScale = 1.0f;
    Matrix.setIdentityM(mScaleMatrix, 0);
    Matrix.scaleM(mScaleMatrix, 0, mRoom.mScale, mRoom.mScale, mRoom.mScale);

    float[] scaleTempMatrix = new float[16];
    Matrix.multiplyMM(scaleTempMatrix, 0, mMVPMatrix, 0, mScaleMatrix, 0);

    mRoom.draw(scaleTempMatrix);

当我设置例如:

mRoom.mScale = 3.0f;

Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -2.0f, 0f, 0f, 0.0f, 1.0f, 1.0f, 0.0f);

我的相机应该在 (0, 0, -2) 处看着 (0,0, -1),它应该在白色立方体内(因为比例是 3.0,所以坐标应该是从 -3 到 3 右?) 但是我得到的只是一个白色的屏幕,里面没有旋转较小的立方体:/

【问题讨论】:

  • Emm,好吧...所以...在您看来...我应该如何处理它?另外......如果我将相机设置为(0,3,3),比例因子为3x,我可以看到里面的旋转立方体......但还有另一个问题......有一个黑色方块......就像那里是一堵 OpenGL 不再绘制的墙,东西消失在这堵墙后面。 “z”值有什么限制吗?
  • 限制由您的投影矩阵定义。使用单位矩阵,视口在所有方向上显示范围 [-1,1] 内的坐标。当您缩放传入的坐标时,您已经从 (-1,-1,-1) 到 (1,1,1) 绘制的立方体变为 (-3,-3,-3) 到 (3,3, 3)。但可见范围仍然是[-1,1]。所以几乎立方体的每个部分都被剪掉了,你什么也看不到。如果将其缩放 1/3 而不是 3,您会看到一个更小的立方体。或者,您可以重新缩放投影矩阵以增加观看量。

标签: android opengl-es glulookat


【解决方案1】:

如果在此代码中您的比例是 3x,那么您的可见坐标范围实际上将是 [-1/3,1/3]。

您正在向后考虑事情,如果您考虑应用缩放操作的顺序可能会有所帮助。现在您正在缩放对象空间坐标,然后应用视图矩阵,然后进行投影。看起来可能不是那样,但这就是 GL 中矩阵乘法的工作原理; GL 在进行矩阵乘法时有效地翻转操作数,并且矩阵乘法不是可交换的。

我相信这是你真正想要的:

public void onDrawFrame(GL10 unused) {
    float[] scratch = new float[16];
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -5.0f, 0f, 0f, -1.0f, 0f, 1.0f, 0.0f);

    mRoom.mScale = 3.0f;
    Matrix.setIdentityM(mScaleMatrix, 0);
    Matrix.scaleM(mScaleMatrix, 0, mRoom.mScale, mRoom.mScale, mRoom.mScale);

    Matrix.multiplyMM(mMVPMatrix, 0, mScaleMatrix, 0, mProjectionMatrix, 0);
    Matrix.multiplyMM(mMVPMatrix, 0, mMVPMatrix,   0, mViewMatrix,       0);

    mRoom.draw(mMVPMatrix);

【讨论】:

  • 我使用了您的代码(稍作更改,使其适合我的整个项目),然后将截锥体更改为:Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1 , 1, 10);现在我有一个白色的背景,里面有一个旋转的立方体......正如我想要的......我认为它有效......需要添加一些闪电以确保它是我想要的方式:D 谢谢队友! (哦,你的代码不见了……把它带回来,很有帮助!)
  • @L3M0L:啊,对不起 - 我不想在没有定义投影矩阵的情况下将实际代码添加到问题中。它不是单位矩阵,因此某些解释无效(例如,坐标范围不是 [-1,1]^3)。您有 3 个不同的坐标范围:X [-ratio,ratio] Y [-1,1] 和 Z [1, 10]。最有可能造成问题的是 X 和 Y。为了确保缩放跨越 Y=[-1,1] 3x 的对象会将其推到视口之外,我不知道 ratio 有什么值,但是我认为它是
  • 谢谢伙计!你帮了我很多!而且,您还向我解释了一些我没有正确理解的事情。谢谢! :)
猜你喜欢
  • 1970-01-01
  • 2015-08-08
  • 2011-06-14
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多