在OpenGL中渲染立方体时遇到问题。我正在绘制两个立方体,一个是线立方体,以原点为中心,而另一个偏离原点并且是实心的。我已经映射了一些键来将对象旋转一定度数到原点,因此整个场景可以围绕原点旋转。
问题是,当我渲染场景时,当线立方体应该位于另一个立方体的前面时,它不能正确显示。
在上图中,彩色立方体应该位于线立方体的后面。即绿线立方体应位于顶部。
此外,立方体的行为也不正常。
围绕x轴(当前水平线)旋转一下后。
多维数据集缺少面并且无法正确呈现。 我做错了什么?
我编码了以下内容 请注意,rotateX,rotateY,rotateZ映射到键,并且是我的全局旋转变量。
//The Initialize function, called once:
void Init(){
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Depth Buffer Setup // Enables Depth Testing
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glEnable(GL_LIGHTING);
}
void draw(){
//The main draw function
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
gluPerspective(45, 640/480.0, .5, 100);
glMatrixMode(GL_MODELVIEW); //select the modelview matrix.
glLoadIdentity ();
gluLookAt(0,0,5,
0,0,0,
0,1,0);
glRotatef(rotateX,1,0,0);
glRotatef(rotateY,0,1,0);
glRotatef(rotateZ,0,0,1);
drawScene(); // this just draws the main axis lines,
glutWireCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(-2,1,0);
drawNiceCube();
glPopMatrix();
glutSwapBuffers();
}
drawNiceCube()的代码只是使用GL_QUADS,而drawWireCube是在GLUT中内置的。
编辑: 我在http://pastebin.com/p1kwPjEM发布了完整的代码,如果没有详细记录,请对不起。
答案 0 :(得分:4)
您是否还要求一个带深度缓冲区的窗口?
glutInitDisplayMode( ... | GLUT_DEPTH | ...);
你有什么地方可以进行面部剔除吗?
glEnable(GL_CULL_FACE);
答案 1 :(得分:1)
这可能是顺时针的原因
10.090面部剔除如何工作?为什么它不使用表面法线?
OpenGL面部剔除计算窗口坐标空间中填充图元的有符号区域。当窗口坐标为逆时针顺序时,有符号区域为正,顺时针方向为负。应用程序可以使用glFrontFace()来指定逆时针或顺时针的顺序,将其解释为前向或后向基元。应用程序可以通过调用glCullFace()指定剔除前面或后面。最后,必须通过调用glEnable(GL_CULL_FACE)启用面部剔除;
OpenGL使用原始窗口空间投影来确定面部剔除有两个原因。为了创建有趣的光照效果,通常需要指定与被近似表面不正交的法线。如果将这些法线用于面部剔除,则可能会导致某些基元被错误地剔除。此外,点积剔除方案可能需要矩阵求逆,这并不总是可行的(即,在矩阵是单数的情况下),而DC空间中的有符号区域总是被定义。
但是,一些OpenGL实现支持GL_EXT_ cull_vertex扩展。如果存在此扩展,则应用程序可以在对象空间中指定均匀的眼睛位置。基于当前法线的点积和从顶点到眼睛的矢量,顶点被标记为剔除。如果基元的所有顶点都被剔除,则不会渲染基元。在许多情况下,使用此扩展程序
来自here
您也可以阅读here
答案 2 :(得分:0)
“@ JonathanSimbahan:你的部分代码是多余的,但缺少一些东西:你忘了调用Init();在创建你的GLUT窗口之后,因此深度测试和所有其他状态永远不会被启用。我建议你根本不使用Init并将其代码移动到它实际所属的绘图代码中。“