反走样

走样(Aliasing)是由于像素离散采样导致的锯齿、闪烁等问题。反走样技术通过混合像素颜色来平滑边缘。OpenGL中主要针对点、线条和面等进行反走样处理。

线条和点反走样

对点和线形图形元素进行反走样的代码如下所示。

code.vb.net
' 启用平滑
Gl.glEnable(Gl.GL_LINE_SMOOTH)
Gl.glEnable(Gl.GL_POINT_SMOOTH)  ' 设置最佳质量提示
Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_NICEST)
Gl.glHint(Gl.GL_POINT_SMOOTH_HINT, Gl.GL_NICEST)
' 启用混合(平滑必需)
Gl.glEnable(Gl.GL_BLEND)
Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA)
' 设置线宽和点大小
Gl.glLineWidth(1.5F)
Gl.glPointSize(3.0F)

多边形面反走样

对多边形面进行反走样的代码如下所示。

code.vb.net
Gl.glEnable(Gl.GL_POLYGON_SMOOTH)
Gl.glHint(Gl.GL_POLYGON_SMOOTH_HINT, Gl.GL_NICEST)  ' 多边形也需要启用混合
Gl.glEnable(Gl.GL_BLEND)
Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA)

反走样示例

第3章绘制了直线段、矩形和圆等图形元素,本例在该例的基础上对各图形元素进行反走样,代码如下所示。

code.vb.net
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Gl.glClear(Gl.GL_COLOR_BUFFER_BIT Or Gl.GL_DEPTH_BUFFER_BIT)
        Gl.glEnable(Gl.GL_LINE_SMOOTH)
        Gl.glEnable(Gl.GL_BLEND)
        Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA)
        Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_NICEST)
        Gl.glPushMatrix()
        Gl.glColor3d(1.0#, 0.0#, 0.0#)
        Gl.glLineWidth(2)
        Gl.glBegin(Gl.GL_LINES)
        Gl.glVertex3d(5, 13, 0)
        Gl.glVertex3d(12, 5, 0)
        Gl.glEnd()
        Gl.glPopMatrix()
        Gl.glFinish()
        Gl.glDisable(Gl.GL_LINE_SMOOTH)
        Gl.glDisable(Gl.GL_BLEND)
        SimpleOpenGlControl1.SwapBuffers()
    End Sub
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Gl.glClear(Gl.GL_COLOR_BUFFER_BIT Or Gl.GL_DEPTH_BUFFER_BIT)
        Gl.glEnable(Gl.GL_LINE_SMOOTH)
        Gl.glEnable(Gl.GL_BLEND)
        Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA)
        Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_NICEST)
        Gl.glPushMatrix()
        Gl.glColor3d(0.0#, 0.0#, 1.0#)
        Gl.glLineWidth(2)
        Gl.glBegin(Gl.GL_LINES)
        Gl.glVertex3d(-3, 5, 0)
        Gl.glVertex3d(-3, -5, 0)
        Gl.glVertex3d(-3, -5, 0)
        Gl.glVertex3d(3, -5, 0)
        Gl.glVertex3d(3, -5, 0)
        Gl.glVertex3d(3, 5, 0)
        Gl.glVertex3d(3, 5, 0)
        Gl.glVertex3d(-3, 5, 0)
        Gl.glEnd()
        Gl.glPopMatrix()
        Gl.glFinish()
        Gl.glDisable(Gl.GL_LINE_SMOOTH)
        Gl.glDisable(Gl.GL_BLEND)
        SimpleOpenGlControl1.SwapBuffers()
    End Sub
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Dim sngX(51) As Single
        Dim sngY(51) As Single
        Dim sngZ(51) As Single
        Dim sngAngStep As Single
        Dim sngTemp As Single
        Gl.glClear(Gl.GL_COLOR_BUFFER_BIT Or Gl.GL_DEPTH_BUFFER_BIT)
        sngAngStep = 6.2832 / 50
        For intI = 1 To 51
            sngTemp = intI * sngAngStep
            sngX(intI) = 8 * Cos(sngTemp) + 0.0#
            sngY(intI) = 8 * Sin(sngTemp) + 0.0#
            sngZ(intI) = 0.0#
        Next
        Gl.glLineWidth(2)
        Gl.glColor3f(0.0#, 1.0#, 0.0#)
        Gl.glEnable(Gl.GL_LINE_SMOOTH)
        Gl.glEnable(Gl.GL_BLEND)
        Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA)
        Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_NICEST)
        Gl.glPushMatrix()
        For intI = 1 To 50
            Gl.glBegin(Gl.GL_LINES)
            Gl.glVertex3d(sngX(intI), sngY(intI), 0)
            Gl.glVertex3d(sngX(intI + 1), sngY(intI + 1), 0)
            Gl.glEnd()
        Next
        Gl.glPopMatrix()
        Gl.glFinish()
        Gl.glDisable(Gl.GL_LINE_SMOOTH)
        Gl.glDisable(Gl.GL_BLEND)
        SimpleOpenGlControl1.SwapBuffers()
    End Sub
    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        Me.Dispose()
    End Sub

运行代码,生成图形如图4-2所示。

Document Image
\[\]

图4-2 绘制图形并进行反走样