绘制线形图元

线形图形元素包括直线段、矩形、圆、多义线和封闭多边形等。

绘直线段

用GL glBegin(Gl.GL_LINES)…GL.gEnd()结构绘制直线段,在结构中用GL.glVertex3D函数定义直线段的起点和终点。代码结构如下面代码所示,其中,Gl.glColor3d和GL.glLineWidth函数定义直线段的颜色和线宽。

code.vb.net
Gl.glColor3d(R, G, B)
Gl.glLineWidth(lngLineWidth)
Gl.glBegin(Gl.GL_LINES)
     Gl.glVertex3d(mpntBegin.X, mpntBegin.Y, 0)
     Gl.glVertex3d(mpntEnd.X, mpntEnd.Y, 0)
Gl.glEnd()

绘矩形

矩形有4条边,所以绘制矩形相当于绘制4条直线段。代码如下所示:

code.vb.net
Gl.glColor3d(R, G, B)
Gl.glLineWidth(lngLineWidth)
Gl.glBegin(Gl.GL_LINES)
    Gl.glVertex3d(pt1.X, pt1.Y, 0)
    Gl.glVertex3d(pt2.X, pt2.Y, 0)
    Gl.glVertex3d(pt2.X, pt2.Y, 0)
    Gl.glVertex3d(pt3.X, pt3.Y, 0)
    Gl.glVertex3d(pt3.X, pt3.Y, 0)
    Gl.glVertex3d(pt4.X, pt4.Y, 0)
    Gl.glVertex3d(pt4.X, pt4.Y, 0)
    Gl.glVertex3d(pt1.X, pt1.Y, 0)
Gl.glEnd()

绘圆

在计算机上绘制曲线,实际上是通过多边形逼近来实现的,比如,用一条有10个顶点的多义线逼近一条曲线时,它看起来是一条折线;而用有100个顶点的多义线来逼近时,它看起来就会像一条曲线。

下面的代码中,lngPNum表示多义线的顶点个数,用一个循环计算多义线上每条直线段起点和终点的坐标,然后用第2个循环按照先后顺序进行连线,最后得到的就是一个圆。

code.vb.net
    sngAngStep = 6.2832 / lngPNum
    For intI = 1 To lngPNum + 1
            sngTemp = intI * sngAngStep
            sngX(intI) = sngCircleR * System.Math.Cos(sngTemp) + posCenter.X
            sngY(intI) = sngCircleR * System.Math.Sin(sngTemp) + posCenter.Y
    Next
    Gl.glColor3d(R, G, B)
    Gl.glLineWidth(lngLineWidth)
    For intI = 1 To lngPNum
        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.glBegin(Gl.GL_LINE_STRIP)…Gl.glEnd()结构来实现。这种方法语法上更简洁,只需要在结构中沿逆时针方向指定顶点的坐标就可以了。代码如下所示。

code.vb.net
Gl.glBegin(Gl.GL_LINE_STRIP)
     Gl.glVertex2f(0.0F, 0.0F)
     Gl.glVertex2f(0.5F, 0.5F)
     Gl.glVertex2f(0.5F, -0.5F)
Gl.glEnd()

如果多义线的起点和终点是重合的,那么它构成一个封闭的多边形。可以使用Gl.glBegin(Gl.GL_LINE_LOOP)…Gl.glEnd()结构来进行绘制,如下面代码所示。

code.vb.net
Gl.glBegin(Gl.GL_LINE_LOOP)
     For i As Integer = 0 To 9
         Dim angle As Single = CSng(i * 36.0 * Math.PI / 180.0)
         Gl.glVertex2f(CSng(Math.Cos(angle)), CSng(Math.Sin(angle)))
     Next
Gl.glEnd()

线形图元属性设置

线形图形元素的属性包括线宽、颜色和线型等。

1 线宽

用Gl.glLineWidth()函数定义线宽,在括号中指定线的宽度,单位为像素,例如:

Gl.glLineWidth(2.0F) ' 像素宽度

2 线条颜色

用Gl.glColor3f(()函数定义线的颜色,在括号中指定颜色的R,G,B分量。各分量取0到1之间的小数,如下面代码所示。

code.vb.net
' 红色
Gl.glColor3f(1.0F, 0.0F, 0.0F)
' 黄色
Gl.glColor3f(1.0F, 1.0F, 0.0F)
' 带透明度的RGBA
Gl.glColor4f(0.0F, 1.0F, 0.0F, 0.5F)

3 线型

用Gl.glEnable(Gl.GL_LINE_STIPPLE)…Gl.glDisable(Gl.GL_LINE_STIPPLE)结构定义线型,如下面代码所示。

code.vb.net
Gl.glEnable(Gl.GL_LINE_STIPPLE)
Gl.glLineStipple(factor, pattern)
Gl.glBegin(Gl.GL_LINES)
     Gl.glVertex2f(-0.8F, 0.0F)
     Gl.glVertex2f(0.8F, 0.0F)
Gl.glEnd()
Gl.glDisable(Gl.GL_LINE_STIPPLE)

常用线型图案(16位十六进制)包括:

code.vb.net
Gl.glLineStipple(1, &HF0F0)   ' 点划线 (1111000011110000)
Gl.glLineStipple(1, &HFFFF)   ' 实线
Gl.glLineStipple(1, &H00FF)   ' 点线 (0000000011111111)
Gl.glLineStipple(2, &H00FF)   ' 拉伸的点线

4 点属性

用Gl.glBegin(Gl.GL_POINTS)…Gl.glEnd()结构绘制点。用Gl.glPointSize()函数定义点的大小,用Gl.glVertex2f()函数定义点的坐标。

code.vb.net
Gl.glPointSize(5.0F)           ' 点大小
Gl.glEnable(Gl.GL_POINT_SMOOTH)
Gl.glEnable(Gl.GL_BLEND)
Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA)
Gl.glBegin(Gl.GL_POINTS)
     Gl.glVertex2f(0.0F, 0.0F)
Gl.glEnd()

绘制线形图元示例

本例绘制直线段、矩形和圆等三种线形图元,代码如下所示:

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.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()
        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.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()
        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.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()
        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

运行代码,单击不同的命令按钮,生成不同的线型图元,如图3-1所示。

Document Image
\[\]

图3-1 生成线形图元