如何在没有Z-fighting的情况下在OpenGL中在另一行上绘制一条线

时间:2012-12-04 17:36:07

标签: c++ opengl gpu

我遇到以下问题。虽然glPolygonOffset适用于网格,例如当我尝试在对象顶部绘制线框轮廓时,它对简单线条不起作用。

以下是网格的工作原理:

// draw object  
mTexture.enableAndBind();
gl::color( Colorf( 1, 1, 1 ) );
gl::draw( mVboMesh );
mTexture.unbind();

// overlay wireframe
gl::enableWireframe();
glLineWidth(1);
glEnable( GL_POLYGON_OFFSET_LINE );
glPolygonOffset( -1, -1 );
glColor3f( 0, 0, 1 );
gl::draw( mVboMesh );
glDisable( GL_POLYGON_OFFSET_LINE );
gl::disableWireframe();

mesh

由于某种原因,它不适用于线路。我想要实现的是在网格上绘制坐标框架的箭头。我正在使用与绘制线条时相同的GL_POLYGON_OFFSET_LINE模式,就像我在对象上做线框一样。但是在这种情况下glPolygonOffset( -1, -1 );完全没有区别。我已经尝试过像100这样的巨大值,它也是一样的。绝对没有效果。这就是我正在做的事情:

// enable 3D rendering
gl::enable( GL_CULL_FACE );
gl::enableDepthRead();
gl::enableDepthWrite();

// drawing the grid
int size = 2000;
int step = 25;
gl::color( Colorf( 0.2f, 0.2f, 0.2f ) );
for( float i = -size; i <= size; i += step )
{
    glBegin( GL_LINES );
    glVertex3f( i, 0, -size );
    glVertex3f( i, 0, size );
    glVertex3f( -size, 0, i );
    glVertex3f( size, 0, i );
    glEnd( );
}

// drawing the arrows
glEnable( GL_POLYGON_OFFSET_LINE );
glPolygonOffset( -1, -1 );

glBegin( GL_LINES );
gl::color( Colorf( 1, 0, 0 ) );
glVertex3f( 0, 0, 0 );
glVertex3f( 100, 0, 0 );
gl::color( Colorf( 0, 1, 0 ) );
glVertex3f( 0, 0, 0 );
glVertex3f( 0, 100, 0 );
gl::color( Colorf( 0, 0, 1 ) );
glVertex3f( 0, 0, 0 );
glVertex3f( 0, 0, 100 );
glEnd( );

glDisable( GL_POLYGON_OFFSET_LINE );

// disable 3D rendering
gl::disableDepthWrite();
gl::disableDepthRead();
gl::disable( GL_CULL_FACE );

和我得到的Z战斗的一个例子:

lines

我试过的一次黑客攻击是完美的:

  1. 禁用深度读取,启用深度写入
  2. 绘制网格
  3. 画箭头
  4. 启用深度阅读
  5. 绘制其他对象
  6. 然而,这是一个非常特殊的情况,虽然它适用于平面网格和箭头,但对于具有复杂形状的其他任何东西都不适用。

    我的问题是:

    1. 为什么glPolygonOffset对于行上行不起作用,而它适用于多边形线?
    2. 如何修复,而不是诉诸于上述黑客攻击,只有在特定情况下才有效?
    3. //我正在使用Cinder作为框架,但是因为我使用的是原始的OpenGL命令而无所谓

      更新

      我已经在第一条评论中检查了答案,并尝试了这种方法,但是那个方法也不起作用,因为结果取决于与相机的距离。

      //// draw coordinate frame and grid
      glDepthRange (0.01, 1.0);
      drawGrid( 2000.0f, 25.0f );
      glDepthRange (0.0, 0.99);   
      gl::drawCoordinateFrame( 100.0f, 5.0f, 2.0f );
      
      glDepthRange (0.0, 1.0);
      
      // draw object  
      

      mix

1 个答案:

答案 0 :(得分:3)

我猜一个黑客可能是将这条线画得更近一点(让我们说更近一点)。这应该避免z战斗。

为此,您可以计算从您的点到POV位置的标准化方向向量。然后使用小因子缩放它,并将其添加到线点坐标