我有一个Opengl ES 1.x ANdroid 1.5应用程序,它在屏幕中央显示一个带有透视投影的Square。
当用户在屏幕上移动手指时,我需要移动相机(不是方形),例如,如果用户将手指向右移动,相机必须向左移动,必须显示就像用户正在移动广场一样。
我需要在不翻译广场的情况下这样做。方块必须位于opengl位置0,0,-1总是。
我不想在正方形周围旋转相机,不,我想要的是将相机左右移动。欢迎使用代码示例,我的opengl技能非常低,而且我无法在Google中找到好的示例
我知道我必须使用这个函数:public static void gluLookAt (GL10 gl, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
,但我不明白在哪里以及如何获取参数的值。因为这样,我将为此做一个代码示例。
例如:
我在位置0,0,-1上有一个立方体。我希望我的相机指向立方体。我尝试了这个:GLU.gluLookAt(gl,0,0,2,0,0,0,0,0,1);但是多维数据集不在屏幕上,我只是知道我做错了什么
答案 0 :(得分:4)
首先,您必须了解在OpenGL中没有不同的模型和视图矩阵。只有一个组合的模型视图矩阵。所以OpenGL不关心(甚至不知道)你是否翻译相机(无论如何是相机?)或物体,所以你不要移动方块的要求完全是人为的。虽然这可能是一个有效的要求,并且模型和视图转换之间的区别通常非常实用,但是不要认为平方转换与从OpenGL的角度转换相机有任何不同。
同样,您不一定需要使用gluLookAt
。与glOrtho
,glFrustum
或gluPerspective
类似,此功能只修改当前选定的矩阵(通常是模型视图矩阵),与glTranslate
,glRotate
或{没有任何区别{1}}功能。当您想要定位经典相机时,glScale
功能会派上用场,但也可以通过调用gluLookAt
和glTranslate
来实现其功能而不会出现问题,有时(根据您的要求)这比人工将您的视图参数映射到glRotate
参数更容易。
现在问题,在没有gluLookAt
的情况下确实很容易解决:你要做的是沿着与屏幕平面平行的方向移动摄像机,这相当于将摄像机移动到视图空间中的xy平面(或相机空间,如果需要)。而这又相当于在视图空间的x-y平面中以相反方向移动场景。
所以需要做的就是
gluLookAt
其中(x,y)是根据触摸事件确定的运动矢量,适当缩放(例如,尝试将屏幕尺寸或类似的触摸线分开)。在此之后glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(x, y, 0.0f);
//camera setup...
会出现您已经拥有的任何其他相机或场景变换(无论是glTranslate
还是只有gluLookAt
次调用)。只需确保glTranslate/glRotate/glScale
是您在设置身份后对模型视图矩阵进行的第一次转换,因为我们想要在视图空间中移动。
所以你甚至不需要glTranslate(x, y, ...)
。从您的其他问题我知道您的代码看起来像
gluLookAt
因此,您需要做的就是将从触摸运动中确定的x和y值插入第一个glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(x, y, z);
glRotatef(...);
...
调用(或将它们添加到已存在的x和y值),因为多个翻译是完全可交换的。
为了更深入地了解OpenGL的转换管道(在进一步推进之前肯定需要),您还可以查看this question的asnwers。
编辑:如果你确实想使用gluLookAt
(无论是相反还是在上述翻译之后),这里有一些关于其工作的小词。它定义了一个使用三个3d矢量的摄像机(每个传递3个连续值)。首先是摄像机的位置(在你的情况下是(0,0,2)),然后是摄像机看起来的点(在你的情况下是(0,0,0),但是(0,0,1)或(0,0) ,-42)会产生相同的相机,方向很重要)。最后是一个向上矢量,定义了摄像机的近似向上方向(通过glTranslate
进一步正交化,以形成适当的正交相机帧。)
但是,由于你的情况下的向上矢量是z轴,这也是负观察方向,这导致奇异矩阵。您可能希望将y轴作为向上方向,这意味着调用
gluLookAt
又相当于一个简单的
gluLookAt(0,0,2, 0,0,0, 0,1,0);
因为您使用负z轴作为查看方向,这也是OpenGL的默认值。