我在我的2D OpenGL应用程序中实现了一个摄像机(模型视图),但在围绕某个点进行缩放以及同时进行平移和围绕某个点缩放方面遇到了一些问题。使用鼠标可以解决这两个问题。平移使用鼠标拖动实现,而围绕点缩放则可以放大/缩小当前鼠标位置周围的内容。
只要我还没有围绕某个点进行过缩放,那么平移就能正常工作。如果我已经围绕某个点进行了缩放,那么在开始平移时会出现一个初始的“跳跃”,然后它就会平稳地工作。对于第一个点,围绕点进行缩放还好,但对于随后的点,场景会先平移一次,然后再进行围绕当前鼠标点缩放。围绕点缩放的代码如下:
使用glLoadMatrix()加载矩阵以设置堆栈中的顶部矩阵。期望的输出是正常平滑的移动,不会出现额外的跳跃,如平移时,缩放之前也不会有跳跃。所谓跳跃是指场景意外地移动。例如,如果场景是一个大正方形,鼠标位于正方形的中心位置,则在拖动鼠标的同时,正方形应该沿着鼠标的方向移动,而正方形的中心点始终在鼠标下方。但是如果出现了跳跃,鼠标将始终位于正方形的中心,但是平移的开始会使场景发生变化,使得正方形的其他部分现在位于鼠标下方。缩放中的跳跃也类似。如果没有围绕某个点进行缩放,则平移功能正常工作。如果不围绕某个特定点进行缩放,则平移功能也正常工作。
只要我还没有围绕某个点进行过缩放,那么平移就能正常工作。如果我已经围绕某个点进行了缩放,那么在开始平移时会出现一个初始的“跳跃”,然后它就会平稳地工作。对于第一个点,围绕点进行缩放还好,但对于随后的点,场景会先平移一次,然后再进行围绕当前鼠标点缩放。围绕点缩放的代码如下:
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
针对评论添加:
平移代码:
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()加载矩阵以设置堆栈中的顶部矩阵。期望的输出是正常平滑的移动,不会出现额外的跳跃,如平移时,缩放之前也不会有跳跃。所谓跳跃是指场景意外地移动。例如,如果场景是一个大正方形,鼠标位于正方形的中心位置,则在拖动鼠标的同时,正方形应该沿着鼠标的方向移动,而正方形的中心点始终在鼠标下方。但是如果出现了跳跃,鼠标将始终位于正方形的中心,但是平移的开始会使场景发生变化,使得正方形的其他部分现在位于鼠标下方。缩放中的跳跃也类似。如果没有围绕某个点进行缩放,则平移功能正常工作。如果不围绕某个特定点进行缩放,则平移功能也正常工作。