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 的调用?

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

4

3 回答 3

6

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

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

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

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

于 2011-08-28T18:17:35.767 回答
4

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

但实际上,关于 OpenGL 的状态机架构,datenwolf 的方法在概念上更加清晰。

于 2011-08-28T18:30:56.693 回答
1

如果您不调用glLoadIdentity()(将当前矩阵重置为单位矩阵,即撤消gluPerspective()已完成的操作)每一帧,而是小心地推/弹出变换矩阵,您可以很高兴地仅在初始化时调用它。通常每次开始绘图时调用加载标识然后重置它要容易得多。例如:

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

然后稍后:

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

glPushMatrix();
gluLookAt(...);

//draw stuff

glPopMatrix();
于 2011-08-28T17:38:20.770 回答