Introduction to OpenGL (Post #9)

Let's move away from the GDI+ and start rendering with OpenGL.I can't say that CPU rendering is useless since it's always a fast and easy way to create a visualization of your algorithms.

Where to start? We'll have to find a wrapper (graphics library with low level bindings to openGL).

For reference I use openTK (you can add it through Manage NuGet packages). Type in the search text openTK and download it to your project.

I'll post two modules here underneath and then I'll use the code from a previous post to create the same results (this time GPU accelerated).

Our declarations

   Public sRect As Rectangle
    Public dRect As Rectangle

    Public RotateX, RotateY, RotateZ As Integer
    Public TranslateX, TranslateY, TranslateZ As Single

    Public ProjectionType As String = "ORTHOGRAPHIC"
    Public ScreenWidth As Integer = 960
    Public ScreenHeight As Integer = 540

    Public Pitch, Yaw, Roll As Single
    Public FOV As Single = 1.24F

Our main subs

 Public Sub Scene_Build(ByVal Func As String)
        If Func = "PRELOAD" Then
            RenderF("PRELOAD")
        End If
    End Sub

    Public Sub RenderF(ByVal Func As String)

        If Func = "PRELOAD" Then


            GL.Enable(EnableCap.Blend) 'Enable transparency
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha) 'Blend Functionality
            GL.Enable(EnableCap.DepthTest) 'Enabling depth
            GL.DepthFunc(DepthFunction.Lequal) 'First 0, Last 1
            GL.Enable(EnableCap.Texture2D)
            GL.Enable(EnableCap.AlphaTest) 'Edge hardiness
            GL.AlphaFunc(AlphaFunction.Gequal, 0.7F)
            GL.ShadeModel(ShadingModel.Smooth) 'Smooth shading
            GL.ClearColor(Color.Black)

        ElseIf Func = "INVALIDATE" Then

            GL.Clear(ClearBufferMask.ColorBufferBit)
            GL.Clear(ClearBufferMask.DepthBufferBit)

            Dim PerspectiveMat As Matrix4
            'Dim lookat As Matrix4
            If ProjectionType = "ORTHOGRAPHIC" Then
                PerspectiveMat = Matrix4.CreateOrthographicOffCenter(0, ScreenWidth, ScreenHeight, 0, -1200.0F, 1200.0F) 'Matrix4.CreatePerspectiveFieldOfView(1.04, 4 / 3, 1, 10000) 'Setup Perspective
            ElseIf ProjectionType = "PERSPECTIVE" Then
                PerspectiveMat = Matrix4.CreatePerspectiveFieldOfView(FOV, 4 / 3, 1, 10000) 'Setup Perspective
            End If

            GL.MatrixMode(MatrixMode.Projection)
            GL.LoadIdentity()
            GL.LoadMatrix(PerspectiveMat)
            GL.MatrixMode(MatrixMode.Modelview)
            GL.LoadIdentity()
            GL.Viewport(0, 0, ScreenWidth, ScreenHeight) 'Window size

            'Rotating/Translating, we'll look into that later
            GL.LoadIdentity()
            GL.Rotate(Pitch, 1.0F, 0.0F, 0.0F)
            GL.Rotate(Yaw, 0.0F, 1.0F, 0.0F)
            GL.Rotate(Roll, 0.0F, 0.0F, 1.0F)
            GL.Translate(TranslateX, TranslateY, TranslateZ)

            RenderF("DRAW")

        ElseIf Func = "DRAW" Then


        End If

    End Sub


And our first drawing call

    Public Sub DrawQuad(ByVal X As Integer, ByVal Y As Integer, ByVal W As Integer, ByVal H As Integer, ByVal OffsZ As Single, ByVal A As Single, ByVal R As Single, ByVal G As Single, ByVal B As Single)
        GL.Disable(EnableCap.Texture2D)
        GL.AlphaFunc(AlphaFunction.Gequal, 0.1F) '0.7 for good edges but doesn't show shadow
        GL.Begin(PrimitiveType.Quads)
        GL.Color4(R, G, B, A) '0.21F)
        GL.Vertex3(X, Y, OffsZ)
        GL.Vertex3(X + W, Y, OffsZ)
        GL.Vertex3(X + W, Y + H, OffsZ)
        GL.Vertex3(X, Y + H, OffsZ)
        GL.End()
        GL.Enable(EnableCap.Texture2D)
        GL.AlphaFunc(AlphaFunction.Gequal, 0.7F) '0.7 for good edges but doesn't show shadow
    End Sub

Our calls will go inside the "DRAW" func of RenderF So when we call the DrawQuad (with the data we have in a rectangle and our ARGB values) we'll get the following result.

Call : DrawQuad(X, Y, Width, Height, Depth, Alpha, Red, Green, Blue)

Example : DrawQuad(200, 200, 100, 100, 1.0F, 1.0F, 0.2F, 0.4F, 0F)

How does it work? The next image explains what happens inside the DrawQuad call.

Copy the above code, add a timer to your form with this on Tick_Event GLHandler.Invalidate()

Scene_Build("PRELOAD") on our form_load and on our GLcontrol paint event the following

RenderF("INVALIDATE")
GLHandler.SwapBuffers()

That was it. The base code for rendering your scene with openGL is ready.

If you add the code from the previous post (the map making simple-worm algorithm) and call drawquad insted of the GDI+ you'll get the following result, this time rendered on the GPU.





Comments