OpenGL相机在点周围缩放/缩放并平移

4
我在我的2D OpenGL应用程序中实现了一个摄像机(模型视图),但在围绕某个点进行缩放以及同时进行平移和围绕某个点缩放方面遇到了一些问题。使用鼠标可以解决这两个问题。平移使用鼠标拖动实现,而围绕点缩放则可以放大/缩小当前鼠标位置周围的内容。
只要我还没有围绕某个点进行过缩放,那么平移就能正常工作。如果我已经围绕某个点进行了缩放,那么在开始平移时会出现一个初始的“跳跃”,然后它就会平稳地工作。对于第一个点,围绕点进行缩放还好,但对于随后的点,场景会先平移一次,然后再进行围绕当前鼠标点缩放。围绕点缩放的代码如下:
public void scaleToPoint(float scale, float x, float y, float z) {
    root.markAsDirty();
    y = drawableHeight - y - 1;

    // (S(Inverse(T))
    matrix.m03 = -x;
    matrix.m13 = -y;
    matrix.m23 = -z;

    matrix.m00 = matrix.m11 = matrix.m22 = scale;
    matrix.m03 *= matrix.m00;
    matrix.m13 *= matrix.m11;
    matrix.m23 *= matrix.m22;
    matrix.m03 += x;
    matrix.m13 += y;
    matrix.m23 += z;
  }

平移代码只是设置矩阵的平移组件。在这两种情况下,似乎我需要以某种方式撤消先前的平移以避免跳跃,但我看不出如何做到。谢谢。

Nick

针对评论添加:

矩阵是javax.matrix.Matrix4f

平移代码:

public void pan(Vector3f pan) {
    root.markAsDirty();
    matrix.setTranslation(pan);
}

matrix.setTranslation用于设置矩阵的平移分量,即:

matrix.m03 = trans.x; 
matrix.m13 = trans.y;
matirx.m23 = trans.z;

使用glLoadMatrix()加载矩阵以设置堆栈中的顶部矩阵。期望的输出是正常平滑的移动,不会出现额外的跳跃,如平移时,缩放之前也不会有跳跃。所谓跳跃是指场景意外地移动。例如,如果场景是一个大正方形,鼠标位于正方形的中心位置,则在拖动鼠标的同时,正方形应该沿着鼠标的方向移动,而正方形的中心点始终在鼠标下方。但是如果出现了跳跃,鼠标将始终位于正方形的中心,但是平移的开始会使场景发生变化,使得正方形的其他部分现在位于鼠标下方。缩放中的跳跃也类似。如果没有围绕某个点进行缩放,则平移功能正常工作。如果不围绕某个特定点进行缩放,则平移功能也正常工作。

“matrix”是什么,它在你的代码中如何使用?你是通过这个矩阵来乘以你的点吗?你说你展示的函数用于缩放。那么平移代码在哪里呢?请尝试给出一个更具体的例子,包括预期输出和观察到的输出。 - catchmeifyoutry
1个回答

1
你的问题在于,你没有进行增量翻译,而是直接设置了翻译。这在平移时可以工作,但是当你进行缩放时,由于缩放而不存储翻译,在下一次翻译操作时被擦除。因此,我会做的是,不要设置翻译,而是增加它。所以当你拖动鼠标时,从两个gluUnProject调用中获取一个增量,然后将该增量添加到矩阵翻译值中。这样可以防止缩放点周围创建的轻微翻译被擦除。
因此:

这是:

public void pan(Vector3f delta_pan)
{
    root.markAsDirty();
    matrix.m03 += delta_pan.x; 
    matrix.m13 += delta_pan.y;
    matirx.m23 += delta_pan.z;
}

那么在旋转/缩放之后进行翻译吗? - huseyin tugrul buyukisik
嗨,Ned,你能否为Opengl Es2.0在Android中的平移功能提供任何示例代码?我参考了更多链接,但是我无法对平移有清晰的了解。如果您建议任何示例代码,那对我来说很容易理解...提前致谢。 - harikrishnan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接