c++ - 如何在没有 Z-fighting 的情况下在 OpenGL 中绘制一条线

标签 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

我试过的一个 hack 是完美的:

  1. 禁用深度读取,启用深度写入
  2. 绘制网格
  3. 画箭头
  4. 启用深度读取
  5. 绘制其他物体

然而,这是一个非常特殊的情况,虽然它适用于平面网格和箭头,但它不适用于任何其他具有复杂形状的东西。

我的问题是:

  1. 为什么 glPolygonOffset 对 lines-on-lines 不起作用而它适用于 lines-on-polygon?
  2. 我该如何修复它,在不诉诸上述技巧的情况下,只有在非常特殊的情况下才有效?

//我正在使用 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

最佳答案

我想一个技巧可能是将线画得离视点更近一点(比方说更近 0.1)。这应该避免 z-fighting。

为此,您需要计算从您的点到 POV 位置的归一化方向 vector 。然后你用一个小的因子缩放它,并将它添加到你的线点坐标

关于c++ - 如何在没有 Z-fighting 的情况下在 OpenGL 中绘制一条线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13708661/

相关文章:

c++ - 写入纹理 GLSL

c++ - OpenCL 找不到平台?

c - CUDA 中的并行列表缩减

c++ - 是否存在通过引用选择元素和通过指针操作选择元素都有效的情况?

c++ - 确定 QProcess 是否正在等待用户输入

c++ - 如何用C++准确获取Windows操作系统版本?

c++ - 在 C++03 中将 std::string 转换为 int

c++ - OpenGL:两个有两个独立光源的物体围绕着它们旋转

java - 具有多种纹理的立方体

c++ - 统一内存分配cuda的功能关键字