The code above is all that is needed to display our OpenGL images. For this example, though, we have added some animation. Recall that we put a timer on the form in Figure 23-6, 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, which we can do indirectly by calling the Delphi function Invalidate(). In Delphi, because all OCXs are windows, any command or message you can send a window can also easily be sent to an OCX. See Listing 23-6.
Listing 23-6 Timer code to produce the rotating teapot
procedure TMain.Timer1Timer(Sender: TObject); begin // Make rendering context current, then // rotate the scene somewhat gl.MakeCurrent(); gl.Rotate(5.0,0.0,1.0,0.5); gl.MakeNotCurrent(); // Repaint the OCX gl.Invalidate(); end;
Figure 23-7 shows the output from our OpenGL Delphi program.
The WaiteGL OCX was written with Visual C++ and uses MFC version 4.0. This new version of Visual C++ makes OCX development a breeze and will likely spawn dozens of useful and reusable OLE custom controls. The purpose of this chapter is not to explain how to develop OCX controls. We wanted to present one that uses OpenGL, to let you do OpenGL graphics from within Visual Basic, Delphi, or any other environment that supports OCXs.
Nevertheless, the source code for this control is included on the CD in the subdirectory for this chapter. The code was originally generated by the Microsoft Control Wizard and is fully commented. In addition, the methods and flags are separated into four source files to make maintenance easier. The file ocxgl.cpp contains wrappers for all the gl library functions; similarly, ocxgl contains the glu library functions. The file ocxaux.cpp also contains wrappers for the AUX library wireframe and solid objects, such as the teapot. Finally, ocxflags.cpp contains the access functions that retrieve the OpenGL flags and other defines.
The main file of the project is WaiteGLCtl.cpp, which is the code responsible for setting up the rendering context and firing the setup and painting events. Also, any of the wiggle or OpenGL GDI-related functions are wrapped here. In addition, there are accessor functions that will return the device and rendering contexts directly, in case you need them for your own low-level code.
Note that the OCX uses the DLL versions of MFC. For your convenience, the redistributable portions are in the \REDIST subdirectory, as well.
In this chapter we have discussed the possibilities and challenges of using OpenGL from some popular visual development environments. Although direct low-level access to the API is certainly possible from any of these environments, a much easier means of access is provided in the form of an OCX control. Most of the sample programs from this book can easily be implemented in a 4GL using this OCX, and for your benefit some are provided in the supplementary examples.