[英]Problem with creating a 2D interface in a 3D openGL world
我正在做一个项目,要求我创建一个“在顶部”渲染的2D界面或3D世界。 在其他一些论坛上,我读到您可以使用“ GluOrtho2D()”来完成这项工作,并在完成后切换回GluPerspective()。 唯一的是,我为此编写的测试代码仅显示3D世界,而不显示2D四边形。 但是,当我禁用3D渲染代码时,四边形会出现在原本应有的位置。 我将代码精简为仅openGL语句,并将其写在下面。 该代码使用Pyglet库以Python编写。
场景初始化代码:
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, float(width)/height, .1, 10000.)
glMatrixMode(GL_MODELVIEW)
glClearDepth(1.0)
glShadeModel(GL_FLAT)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
框架渲染代码。 对builder.buildMap()的调用将创建3D场景,而glBegin-glEnd对将绘制2D四边形:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
stage.set3DMode(window.width, window.height)
builder.buildMap()
stage.set2DMode(window.width, window.height)
glBegin (GL_QUADS)
glVertex2i(0, 0)
glVertex2i(0, 200)
glVertex2i(200, 200)
glVertex2i(200, 0)
glEnd()
stage.set3DMode函数:
glDisable(GL_DEPTH_TEST)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0, width, 0, height)
glMatrixMode(GL_MODELVIEW)
和stage.set3DMode函数:
glEnable(GL_DEPTH_TEST)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, float(width)/float(height), .1, 10000.)
glMatrixMode(GL_MODELVIEW)
我真的希望有人能指出我的错误! 并感谢您对我的帮助:)
切换到GL_MODELVIEW后,您似乎没有调用glLoadIdentity()
。 记住的最简单方法是,每次更改投影矩阵时都调用它,切换到GL_MODELVIEW并调用glLoadIdentity()
(除非您真的想保留旧的)。
很多人误会如何使用glViewport等。 他们总是将其放置在重塑回调中,这是完全错误的。
在需要这些设置之前,您始终要在渲染功能中进行完整设置。 因此,您的代码应为(伪代码):
render_scene():
// first clear the whole window
glViewport(0, 0, window.width, window.height)
glClearDepth(1.0)
glClearColor(1., 1., 1., 1.);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
glViewport(3Dstuff.x, 3Dstuff.y, 3Dstuff.w, 3Dstuff.h)
// maybe also set scissor to clip
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60.0, float(width)/height, .1, 10000.)
glMatrixMode(GL_MODELVIEW)
setup3DstuffModelview()
glDepthFunc(...)
glEnable(GL_DEPTH_TEST)
// other state stuff
render3Dstuff()
// now the 2D stuff
glViewport(2Dstuff.x, 2Dstuff.y, 2Dstuff.w, 2Dstuff.h)
// clear depth and stencil -- if you need parts of the 3D depth / stencil
// for some algorithm retain it or save and restore by FBO renderbuffers or
// glReadPixels, glDrawPixels
glClearDepth(1.0)
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(...)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
setup2DstuffModelview()
glDepthFunc(...)
glDisable(GL_DEPTH_TEST)
// other state stuff
render2Dstuff()
// repeat for all the layers you need
这真的很重要:OpenGL是状态机。 除非可以证明没有发生不确定的状态变化,否则在渲染特定几何图形之前,您总是要重新设置所有所需的状态。
我将以下矩阵用于2D渲染:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, w, h, 0, 0, 1);
glViewport(0, 0, w, h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.375f, 0.375f, 0);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.