走样(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所示。
\[\]
图4-2 绘制图形并进行反走样