WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Using OpenGL with VB.NET

by Jacek Artymiak
04/28/2003

Although VB.NET is not the first programming language that comes to mind when you are thinking of writing applications that use the OpenGL API, it is possible (and not that difficult), if you are willing to dip your toes in the warm waters of open source software. OpenGL was originally developed by SGI, and is now available in commercial and free incarnations. In case you have never heard of it, OpenGL is an industry standard multi-platform API for 3D graphics supported by virtually all of the major players in the broadly defined field of computer graphics, computer animation, multimedia, and computer games. On Windows 2000/XP you should have a copy in your C:\WINNT\System\system32 directory (look for OPENGL32.DLL). In this article, I will show you how to quickly write a basic OpenGL application in VB.NET using clever open source glue to make it all work together.

Basic Tools

I assume that you are using VB.NET or a full version of the Visual Studio .NET and the .NET Framework SDK.

Next, you will need a copy of the CsGL library, written by the team of developers headed by Lloyd Dupont. CsGL is not another implementation of OpenGL, but a set of wrappers for the OpenGL DLL that glue your C# or VB.NET applications to OpenGL proper. It is written with C# programmers in mind, but it works rather well with VB.NET. The library has a BSD-like license, which means that you can use it in commercial applications, if you obey its (very liberal) terms.

CsGL installation is very simple. Just download the binary distribution (I used version 1.4.1), unpack it with a tool like WinZip, and run the installation script that comes with CsGL. That's it!

Your First Project

Start Visual Studio, and choose File->New->Project. In the New Project dialog, select Visual Basic Application and Windows Application. Click OK, and you should see the default rectangular form of your application. Right-click on the form and choose View Code. You should now see this snippet of code:


Public Class Form1 Inherits System.Windows.Forms.Form

   Windows Form Designer generated code

End Class

Right-click on the References item in the Solution Explorer window and select Add Reference. In the Add Reference dialog, click on the Browse button and locate csgl.dll. Look for it in the same place where you found OPENGL32.DLL, possibly C:\WINNT\System\system32. Select it, click on the Open button in the file dialog, then click on the OK button in the Add Reference dialog. A reference to CsGL has now been added to your project.

Now let's return to the code of your application. Click on the plus (+) sign next to the "Windows Form Designer generated code" label, to expand the skeleton code. You should see this:


Public Class Form1
    Inherits System.Windows.Forms.Form

  #Region " Windows Form Designer generated code "

    Public Sub New()
      MyBase.New()

      'This call is required by the Windows Form Designer.
      InitializeComponent()

      'Add any initialization after the 
      'InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose _
                              (ByVal disposing As Boolean)
      If disposing Then
        If Not (components Is Nothing) Then
          components.Dispose()
        End If
      End If
      MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the 
    'Windows Form Designer It can be modified using the 
    'Windows Form Designer.  Do not modify it using the 
    'code editor.
    <System.Diagnostics.DebuggerStepThrough()> 
    Private Sub InitializeComponent()
      components = New System.ComponentModel.Container()
      Me.Text = "Form1"
    End Sub

  #End Region

End Class

You will now have to modify this skeleton in the following way:

  • Import CsGL.
  • Define two new properties: view (viewport) and thrOpenGL (an OpenGL thread).

This is accomplished with:


Imports CsGL.OpenGL
Public Class Form1
  Inherits System.Windows.Forms.Form
  Private view As myOpenGL.myView
  Private thrOpenGL

Next, you need to initialize view and thrOpenGL:


#Region " Windows Form Designer generated code "

  Public Sub New()
    MyBase.New()

    'This call is required by the Windows Form Designer.
    InitializeComponent()

    'Add any initialization after the InitializeComponent() call

    Me.view = New myOpenGL.myView()
    Me.view.Parent = Me
    Me.view.Dock = DockStyle.Fill
    Me.thrOpenGL = New Threading.Thread(AddressOf OpenGL_Start)
    Me.thrOpenGL.Start()

  End Sub

#End Region

When thrOpenGL is initialized, it is given a reference to the OpenGL_Start method, which takes care of refreshing the viewport:


Private Sub OpenGL_Start()
  While 1 = 1
    Me.view.Refresh()
  End While
End Sub

Once we have taken care of the start of the OpenGL thread, the next step is adding code that terminates it. This is the job of a modified version of the default Dispose() method.


'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
  If disposing Then
    If Not (components Is Nothing) Then
      components.Dispose()
    End If
  End If
  MyBase.Dispose(disposing)
  Me.thrOpenGL.Abort()
End Sub

As you can see, all that was required was an addition of a call to Me.thrOpenGL.Abort().

Next we need to add a large chunk of code that does the real work. In the myOpenGL namespace, define the class myView, which inherits CsGL.OpenGL.OpenGLControl and overrides a few of its methods, overloads some of them as needed, and defines a keyboard handler.

Namespace and class definition, and inheritance of OpenGLControl, are taken care of by these lines of code:


Namespace myOpenGL
  Public Class myView
    Inherits OpenGLControl

The next step is a bit unusual, because it defines constants that are normally found in the gl.h and glu.h header files. For some reason, I could not access them in the same way as the methods and classes of CsGL, but I found a way around it. I run these commands to create code that can be put directly into the Private Enum GLConstants ... End Enum block:


$ awk '/#define/ { print $2 " = 
                    &H" substr($3, 3) }' gl.h > glconst
$ awk '/#define/ { print $2 " = 
                    &H" substr($3, 3) }' glu.h > gluconst

For this example, the list of constants should look like this:


Private Enum GLConstants
  GL_COLOR_BUFFER_BIT = &H4000
  GL_DEPTH_BUFFER_BIT = &H100
  GL_SMOOTH = &H1D01
  GL_DEPTH_TEST = &HB71
  GL_LEQUAL = &H203
  GL_PERSPECTIVE_CORRECTION_HINT = &HC50
  GL_NICEST = &H1102
  GL_PROJECTION = &H1701
  GL_MODELVIEW = &H1701
  GL_POLYGON = &H9
End Enum

If you don't have an AWK interpreter installed on your machine, you can find it in at least three places: cygwin, unxutils, or Windows Services for UNIX. Some of these packages may contain the gawk interpreter, which is the GNU implementation of AWK that can be used instead of awk. You will also need the gl.h and glu.h header files, which you can get from SGI or from Mesa.

Pages: 1, 2

Next Pagearrow