如何正确设置OpenGL场景以便可视化单个对象


2

我需要为我的网格工具包编写一个简单的可视化工具。我正在使用的对象始终位于[-1,1]^3框(含)内,因此我需要确保该对象将完全由用户可见。我也想有一个可能性,像用户在对象周围“飞行”一样旋转对象周围的相机。

这就是我正在做的:

static void Reshape(int w, int h) 
{ 
    glViewport(0,0,(GLsizei) w, (GLsizei) h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    float maxDistance = sqrt(2); 
    if (w <= h) 
    { 
     glOrtho(-maxDistance, maxDistance, -maxDistance * (GLfloat)h/(GLfloat)w, 
      maxDistance * (GLfloat)h/(GLfloat)w, -6.0, 6.0); 
    } 
    else 
    { 
     glOrtho(-maxDistance * (GLfloat)w/(GLfloat)h, maxDistance * (GLfloat)w/(GLfloat)h, 
      -maxDistance, maxDistance, -6.0, 6.0); 
    } 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 

static void PolarView(GLdouble distance, GLdouble twist, GLdouble elevation) 
{ 
    double centerx, centery, centerz; 
    double eyex, eyey, eyez; 

    eyex = distance * cos(-twist) * cos(elevation); 
    eyey = distance * sin(-twist) * cos(elevation); 
    eyez = distance * sin(elevation); 
    centerx = centery = centerz = 0; 

    gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0, 0, 1); 
} 

的重塑功能在初始设置和可视化控制的每一个调整大小后调用,PolarView函数调用的每个重绘与某些角度和距离大比3的平方根(真的很重要?)。该代码可以很好地处理像立方体或球体这样的凸对象,但是它在圆环对象上有一些问题(通过其他方面可以看到一些面孔),所以我相信这是关于深度测试的。我的设置有什么问题?截图:
Bad torus http://s5.tinypic.com/1039b1y.jpg
Bad torus filled http://s5.tinypic.com/2h54paf.jpg
我做了一些网络上搜索,发现了这样的问题在情况发生时,有什么问题我近及远平面参数。在我的情况下,这些值是什么? 我的绘画过程是这样的:

glEnable(GL_DEPTH_TEST); 
glClearDepth(1); 
glPolygonMode(GL_FRONT, GL_LINE); // Changing of GL_LINE to GL_FILL doesn't fixing my problem, it just changing the appearance of the model. 
glClearColor(BackColor.R/255.0f, BackColor.G/255.0f, BackColor.B/255.0f, 1); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glLoadIdentity(); 
PolarView(sqrt(3), _phi, _theta); 
// .. only draws 

我PIXELFORMATDESCRIPTOR:

 PIXELFORMATDESCRIPTOR pfd = 
    { 
     sizeof(PIXELFORMATDESCRIPTOR), 
     1, 
     PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, 
     PFD_TYPE_RGBA, 
     24, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     0, 
     32, // Depth buffer size 
     0, 
     0, 
     PFD_MAIN_PLANE, 
     0, 
     0, 
     0, 
     0 
    }; 

我已经找到一些方法来解决此:

  • 交换价值为我近及远飞机
  • 将glDepthFunc设置为GL_GREATER,并将g lClearDepth为0
    好的,如果偶数个错误发生,我的代码将会正常工作。但是第一个错误在哪里?
  0

您需要更详细地说明问题所在。这很难理解。甚至可能是一个屏幕截图? 22 2月. 092009-02-22 14:54:03

0

“8.070如何可以自动计算显示我整个模型的视图?(我知道边界球和向上向量。)”在OpenGL FAQ 8入境回答我的问题。但是,我的设置稍有不同,下面是我重写的PolarView和Reshape功能:

static void Reshape(int w, int h) 
{ 
    float diameter = sqrt(3); 
    glViewport(0, 0, (GLsizei)w, (GLsizei)h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    GLdouble zNear = 1; 
    GLdouble zFar = zNear + diameter * 2; 
    GLdouble left = -diameter; 
    GLdouble right = diameter; 
    GLdouble top = -diameter; 
    GLdouble bottom = diameter; 
    double aspect = (double)w/(double)h; 
    if (aspect < 1) 
    { 
     bottom /= aspect; 
     top /= aspect; 
    } 
    else 
    { 
     left *= aspect; 
     right *= aspect; 
    } 
    glOrtho(left, right, bottom, top, zNear, zFar); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 

static void PolarView(GLdouble twist, GLdouble elevation) 
{ 
    float diameter = sqrt(3); 
    double distance = diameter * 2; 
    double centerx, centery, centerz; 
    double eyex, eyey, eyez; 

    eyex = distance * cos(twist) * cos(elevation); 
    eyey = distance * sin(twist) * cos(elevation); 
    eyez = distance * sin(elevation); 
    centerx = centery = centerz = 0; 
    gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, 0, 0, 1); 
} 

2

你看过OpenGL FAQ 12吗?

看起来可疑的代码是负面的近平面。负Z值位于相机后面,渲染3D场景时通常是错误的。但是,这本身不应该导致你所看到的问题,Z的范围[-6,6]应该为这种场景提供足够的精度。

你打电话给glEnable(GL_DEPTH_TEST)?你是否通过GL_DEPTH_BUFFER_BITglClear每帧?

更新:您打电话glPolygonMode(GL_FRONT, GL_LINE)。这意味着前向三角形只在轮廓上绘制,这意味着如果前向三角形A与另一个前向三角形B重叠,则可以通过A看到B的边缘。对于凸面体,这不会发生,所以你没有注意到这个问题。

如果你想要三角形遮住它们后面的三角形,那么你将需要使用GL_FILL模式填充它们。为了得到一个线框图,你需要画用白色填充的模型,然后用黑色的轮廓再次绘制模型,这样的:

 
glDepthFunc(GL_LEQUAL); 
glPolygonMode(GL_FRONT, GL_FILL); 
/* draw the model in white */ 
glDepthFunc(GL_EQUAL); 
glPolygonMode(GL_FRONT, GL_LINE); 
/* draw the model again in black */ 

的想法是,在第二次在模型中,我们只希望绘制轮廓线,这些轮廓不会被靠近相机的第一遍中绘制的某个三角形遮挡(即Z轴较低)。

另一个想法:我认为你的相机可能指向了错误的方向。这可以解释为什么现场被glOrtho视角错误地绘制,而与glFrustum视角完全不同。在glOrtho的情况下,整个场景正在绘制后面的相机;这就是为什么它正在用Z顺序绘制错误的方式。当你将近平面设置为正数时,整个场景被剔除。

  0

该链接没有帮助我。我在我的问题中添加了更多代码。 22 2月. 092009-02-22 17:24:34

  0

不管我如何绘制多边形(GL_LINE或GL_FILL),问题仍然存在。有没有任何证据表明GL_LINE渲染不应该使用深度缓冲区? 22 2月. 092009-02-22 18:03:36

  0

你可以截取我上面推荐的模型吗? 22 2月. 092009-02-22 18:12:56

  0

上传了带平面填充面的新渲染模型。 22 2月. 092009-02-22 18:26:03

  0

你正在使用glOrtho,这使得有点难以辨别(看)哪些三角形是近/远的。如果在生成网格时遇到问题,则必须按特定顺序生成三角形。见http://home.comcast.net/~fbui/glCullFace.html 22 2月. 092009-02-22 18:31:07

  0

参见http://home.comcast.net/~fbui/glFrontFace.html 22 2月. 092009-02-22 18:32:06

  0

我认为很明显,剔除工作正常 - 我们可以只能看到朝前的三角形。这是深度缓冲区不起作用。你确定你在调用glDepthFunc(GL_LEQUAL)吗? 22 2月. 092009-02-22 18:39:00

  0

glDepthFunc的默认值是GL_LESS,应该没问题,所以这可能不是问题。 22 2月. 092009-02-22 18:47:55

  0

如果您尝试使用glFrustum而不是glOrtho,场景会是什么样子? (确保你使用正的近平面) 22 2月. 092009-02-22 18:48:45

  0

如果我将使用glFrustum(-maxDistance,maxDistance,-maxDistance,maxDistance,0.1,10),则渲染区域将为空。 23 2月. 092009-02-23 01:33:50

  0

我发现如何解决这个问题。但是我怎样才能正确设置我的相机?我需要确保从某个恒定距离看我的模型中心。我的PolarView功能有什么问题? 23 2月. 092009-02-23 03:26:04