The other event you must support is the Render event. This event is fired by the control whenever its window needs repainting. In this function you will place your code that accesses the OCX’s methods to do the actual rendering. Listing 23-2 is the Visual Basic code that draws a wireframe teapot from the AUX library.
Note that the rendering context is first made current, then made not current after the drawing code. This is not strictly necessary if you have only one control and rendering context, but it ensures that no code changes are needed later if you add another control. After the rendering context is made not current, you must call SwapBuffers to bring the image to the foreground.
Listing 23-2 Visual Basic code to draw the AUX library teapot
Private Sub gl_Render() Rem Make the rendering context current gl.MakeCurrent Rem Clear the screen and draw the aux lib teapot gl.Clear (gl.glColorBufferBit) gl.auxWireTeapot (55#) Rem Flush the commands, make rendering context Rem not current, and then finally swap buffers gl.Flush gl.MakeNotCurrent gl.SwapBuffers End Sub
The code above is all that is needed to display our OpenGL images. For this example, though, we have added some animation. We put a timer on the form shown in Figure 23-2, and set the interval to 200 milliseconds. Every time this timer fires, our function will make the rendering context for our OCX current, rotate the viewing matrix by 5?, and then clean up by making the rendering context not current. Finally, we tell the control to repaint, by calling the gl_Render function directly. See Listing 23-3.
Listing 23-3 Timer function that rotates the viewing volume by 5?
Private Sub Timer_Timer() Rem Make the rendering context current gl.MakeCurrent Rem Rotate 5 degrees gl.Rotate 5#, 0#, 1#, 0.5 Rem Make rendering context not current, then Rem force a redraw gl.MakeNotCurrent gl_Render End Sub
The completed Visual Basic program is shown running in Figure 23-3.
To make use of WaiteGL.ocx, it must first be registered as an OCX by the operating system (Windows NT or Windows 95). Copy the .ocx file into your system directory and run the supplied ocxreg.exe program. In the command line argument, specify the .ocx filename and either install or uninstall. For example:
ocxreg.exe WaiteGL.ocx install
You will find this program (with source) provided on the CD under the subdirectory for this chapter.
Once the control has been registered with the operating system, it must be installed into the Delphi Tool palette. Select Component from the main menu, then Install. Click the OCX button, and the dialog shown in Figure 23-4 will display a list of registered OCX controls that can be installed.
Select the Waite Group OpenGL OXC and then click on OK. This installs the OCX into the Delphi tool palette for your use. Just drag the control onto your forms and you will have a window for OpenGL rendering.
For our Delphi example, we start with a new form and place our OpenGL OCX in the middle, taking up most of the client area. We’ll also put a timer on the form to do some animation. Figure 23-5 shows the completed form. You may notice that the control does not paint or erase its client area. This is because the drawing code must be written in Pascal and placed in the OnRender event.
Our Object Inspector Events tab shown in Figure 23-6 shows two events that are unique to this control: OnRender and OnSetupRC.
Double-click on the OnSetupRC and the glSetupRC function is created. Your editor is opened to allow this function to be defined. The code in Listing 23-4 shows the setup, making the background color black and initializing an orthogonal viewing volume.
Listing 23-4 Delphi code called in response to the SetupRC event from the OCX
procedure TMain.glSetupRC(Sender: TObject); begin // Make the Rendering context current gl.MakeCurrent(); // Set the clear color, and viewing volume gl.ClearColor(0.0, 0.0, 0.0, 1.0); gl.LoadIdentity(); gl.Ortho(-100,100,-100,100,-100,100); // Flush the commands and make the rendering context // not current gl.Flush(); gl.MakeNotCurrent(); end;
The glRender function is created in the same way, by double-clicking on the OnSetupRC event. The code for drawing the wireframe teapot is shown in Listing 23-5. Note that the rendering context is first made current, then made not current after the drawing code. This is not strictly necessary if you have only one control and rendering context, but it ensures that no code changes are needed later if you add another control. After the rendering context is made not current, you must call SwapBuffers to bring the image to the foreground.
Listing 23-5 Delphi code called in response to the Render event from the OCX
procedure TMain.glRender(Sender: TObject); begin // Make the rendering context current gl.MakeCurrent(); // Clear the background, and draw a teapot gl.Clear(gl.glColorBufferBit()); gl.Color(0, 0, 255, 255); gl.auxWireTeapot(55.0); // Flush commands, free rendering context, and // swap buffers gl.Flush(); gl.MakeNotCurrent(); gl.SwapBuffers(); end;