2011-08-28 41 views
1
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 

//set viewpoint 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
gluPerspective(VIEW_ANGLE,Screen_Ratio,NEAR_CLIP,FAR_CLIP); 
gluLookAt(0,5,5, 0,0,0, 0,1,0); 

//transform model 1 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glRotatef(Theta, 0,1,0); 

//draw model 1 
glBegin(GL_QUADS); 
... 
glEnd(); 

上面的代码工作正常,但有没有任何方法可以删除对gluPerspective的调用?如何仅使用gluPerspective一次?

我的意思是,我想在初始化时只调用它一次,而不是在每次渲染过程中重复。

+0

因为没有在代码中调用gluPerspective,渲染会导致意想不到的结果。 – jondinham

+0

你为什么如此热衷于避免这种情况? – Flexo

回答

5

你叫gluPerspective那里,因为它属于那里。 OpenGL不是您初始化事物的场景图。这是一个状态驱动的绘图API。投影矩阵是一个状态,每个严肃的图形应用程序在整个单帧渲染过程中多次更改此状态。

OpenGL不知道几何对象,位置和相机。它只是通过处理管道推送点,线和三角形,并将结果绘制到屏幕上。在绘制完东西之后,OpenGL无论如何都没有回忆它。

我的意思是在初始化时只调用它一次。

OpenGL未初始化(除了创建渲染上下文,但实际上这是操作系统的图形堆栈的一部分,而不是OpenGL)。当然,您可以上传纹理并缓冲对象数据,但这可能随时发生。

1

如果你不叫glLoadIdentity()(其重置当前矩阵为单位矩阵,即撤消什么gluPerspective()做)的每一帧,而是仔细push/pop变换矩阵,你可以只在初始化调用逃脱它相当愉快。通常情况下,只要每次开始绘图时调用加载标识然后将其重置,就更容易了。例如: -

// Initalisation 
glLoadIdentity(); 
gluPerspective(...); 

再后来就:

// Drawing each frame 
glClear(...); 

glPushMatrix(); 
gluLookAt(...); 

//draw stuff 

glPopMatrix(); 
+0

确实使用glPushMatrix&glPopMatrix增加了很多性能?相比于将每个对象移动到根(在调用glLoadIdentity的情况下) – jondinham

+0

我不会关注像这样的操作的性能,每帧发生一次。它只是不值得。担心几何,着色器和纹理等等大问题。与那些测量'glLoadIdentity()'+'gluPerspective()'与'glPushMatrix()'+'glPopMatrix()'的成本相比,实际上是不可能的。 – Flexo

4

执行上投影矩阵使用gluLookAt,因为它定义了相机/视图,并且因此属于模型视图矩阵,通常作为最左边的变换(glLoadIdentity后的第一个),其中,它构成了图模型视图的一部分。虽然它也适用于你的方式,但它在概念上是错误的。这也可以解决您的问题,因为您不必每帧触摸投影矩阵。

但实际上,在OpenGL的状态机体系结构中,datenwolf的方法在概念上更清晰。