4

我在 OpenGL 中的渲染深度有问题

以下代码是发生问题的代码的简单示例。它在同一位置渲染 2 个梯形,其中一个旋转。但是旋转的总是显示在顶部,即使它在旋转时应该在第一个梯形后面。

我想我在初始化 OpenGL 时搞砸了。同样在通过stackoverflow搜索时,我发现有人建议执行以下代码并查看输出的帖子。

int depth;
glGetIntegerv(GL_DEPTH_BITS, &depth);
printf("%i bits depth", depth);

那么输出是0位深度,我猜这不好:(

我正在使用带有 glfw 库的 xCode 在 Mac 上开发

#include <GL/glfw.h>
#include <stdlib.h>

int main( void )
{
   int running = GL_TRUE;

   if( !glfwInit() )
   {
      exit( EXIT_FAILURE );
   }

   // Open an OpenGL window
   if( !glfwOpenWindow( 640,480, 0,0,0,0,0,0, GLFW_WINDOW ))
   {
      glfwTerminate();
      exit( EXIT_FAILURE );
   }

   glEnable(GL_DEPTH_TEST);

   float angle = 0;

   // Main loop
   while( running )
   {

      double elapsedTime = glfwGetTime();
      glfwSetTime(0);
      angle += 90 * elapsedTime;

      // OpenGL rendering goes here...
      glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();

      glPushMatrix(); //Save the transformations performed thus far
      glColor3f(1.0f, 1.0, 0.0);
      glTranslatef(0.0f, 0.0f, 0.0f); //Move to the center of the trapezoid
      //glRotatef(angle, 0.0f, 1.0f, 0.0f); //Rotate about the y-axis
      glBegin(GL_QUADS);

      //Trapezoid
      glVertex3f(-0.7f, -0.5f, 0.0f);
      glVertex3f(0.7f, -0.5f, 0.0f);
      glVertex3f(0.4f, 0.5f, 0.0f);
      glVertex3f(-0.4f, 0.5f, 0.0f);

      glEnd();

      glPopMatrix();

      glPushMatrix(); //Save the transformations performed thus far
      glColor3f(1.0f, 0.0, 0.0);
      glTranslatef(0.0f, 0.0f, 0.0f); //Move to the center of the trapezoid
      glRotatef(angle, 0.0f, 1.0f, 0.0f); //Rotate about the y-axis
      glBegin(GL_QUADS);

      //Trapezoid
      glVertex3f(-0.7f, -0.5f, 0.0f);
      glVertex3f(0.7f, -0.5f, 0.0f);
      glVertex3f(0.4f, 0.5f, 0.0f);
      glVertex3f(-0.4f, 0.5f, 0.0f);

      glEnd();

      glPopMatrix(); //Undo the move to the center of the trapezoid

      glfwSwapBuffers();

      // Check if ESC key was pressed or window was closed
      running = !glfwGetKey( GLFW_KEY_ESC ) &&
      glfwGetWindowParam( GLFW_OPENED );
   }

   // Close window and terminate GLFW
   glfwTerminate();
   // Exit program
   exit( EXIT_SUCCESS );
}
4

3 回答 3

5

if( !glfwOpenWindow( 640,480, 0,0,0,0,0,0, GLFW_WINDOW ))

Why do you pass all of those zeros? Those parameters are kind of important. The GLFW reference documentation (pdf) shows that those parameters describe how many bits you want for the colors, depth, and stencil. The next-to-last zero is the number of depth bits. You asked for 0 bits of depth for the framebuffer, so that's what you got.

You can't blame the API for doing what you asked ;)

A more reasonable command would be:

if( !glfwOpenWindow( 640,480, 8, 8, 8, 8, 24, 8, GLFW_WINDOW ))

This gives you 8 bits each for RGBA, 24 for depth, and 8-bits of stencil.

于 2011-06-16T22:55:16.513 回答
2

If you are drawing polygons on top of each other you are not guaranteed the order you draw them in will be the order they are rendered. It may work one way on one driver and another way on the next. Same with drivers from different vendors.

You have to either add a tiny depth difference in your glVertex commands or play with glPolygonOffset(). Or do a glFlush() after the first polygon, which is extremely inefficient.

By using a depth buffer you're telling the graphics card that it can render triangles in whatever order it chooses because the depth buffer will sort out what's drawn in front. This is why in some games you'll see polygons flickering through each other (especially things in the distance) when they map to the same depth value.

于 2011-06-17T01:37:41.500 回答
0

glGetIntegerv( GL_DEPTH_BITS, ..) is deprecated in OpenGL 3

use instead :

int GetDepthBits()
{
  HDC hdc = wglGetCurrentDC();
  int iPixelFormat = GetPixelFormat( hdc);
  int iAttr[] = {WGL_DEPTH_BITS_ARB};
  int iDepthBits;
  wglGetPixelFormatAttribivARB( hdc, iPixelFormat, 0, 1, iAttr, & iDepthBits);
  return iDepthBits;
}
于 2015-03-26T07:24:41.903 回答