Open GL Super Bible

Previous Table of Contents Next

Part IV
OpenGL with. . .

In the fourth and last part of this book, we are going to take a look at some general programming issues that arise when using OpenGL. Two chapters will help C++ programmers who are using the most popular C++ frameworks in use for Windows programmers, MFC and OWL. We won’t be leaving out the 4GL and other visual programmers, either. In Chapter 23 we introduce you to an OpenGL OCX that will facilitate the use of OpenGL from almost any 32-bit Windows programming environment.

Finally, no book on Windows and OpenGL would be complete without addressing the interaction of OpenGL with the other graphics APIs. In addition to GDI, this group includes the DirectX architecture and 3DDDI.

Chapter 21
MFC-Based OpenGL Programming

What you’ll learn in this chapter:

How to… Functions You’ll Use

Set MFC window styles to support OpenGL PreCreateWindow
Create and set up the rendering context OnCreate
Clean up the rendering context when the program terminates OnDestroy
Place your projection and viewport code OnSize
Place your rendering code OnDraw
Prevent screen flicker between renderings OnEraseBkgnd
Place your palette management code OnQueryNewPalette, OnPaletteChanged

It is an undeniable fact that a large and growing number of developers are using C++ for Windows development. Throughout this book, however, we have presented all our source code in C. Fortunately, most C++ programmers can easily follow C source code. On the other hand, unfortunately, the converse is not necessarily true (many C programmers cannot follow C++ as easily). This is not to say that C++ is especially harder to grasp and use, but if you picked up this book on graphics programming, you want to learn graphics programming, you probably don’t want to have to learn some new syntax along the way as well.

Although any of the samples in this book can be compiled with a C++ compiler as well as a C compiler, most C++ programmers developing for Windows are not writing C code. Most are using a commercial C++ application framework package, or their own C++ class hierarchy. The point is, most C++ applications don’t have windows procedures like the ones in this book, nor do they have those “case statements from hell” that handle every conceivable message that may be posted to a window.

The purpose of this short chapter is to give C++ programmers using a popular application framework a starting place for their OpenGL programs. The application framework for this chapter is the Microsoft Foundation Classes (MFC). The samples and screenshots for this chapter were prepared using Microsoft’s Visual C++ 4.0. Other compilers and environments that support MFC should work similarly.

Note:  If you are using OWL (Borland’s Object Windows Library), coverage of it is included in Chapter 22.

For the purposes of this chapter, we will assume that you are already familiar with the following:

  Visual C++ and MFC for building Windows NT and Windows 95 applications
  Chapter 4 of this book, covering OpenGL for Windows and the creation and use of rendering contexts
  The palette handling material in Chapter 8

Isolate Your OpenGL Code

For any application, it is good design practice to keep your source code as modular as possible. By isolating functional pieces, it becomes much easier to reuse and maintain the code. By isolating your “pure” OpenGL code into a separate module, you can efficiently replace this module with specific code, while retaining the functionality of the rest of the application. Our sample here makes it relatively simple to take any C program in this book and convert it to C++, using MFC and our test application shell.

We start by declaring three functions in a C source file called glcode.c. The file glcode.h contains the declarations for these functions and is included for access in our CView-derived class file.

// glcode.h
// Declarations for external OpenGL module.  These functions are
// defined in glcode.c and are called appropriately by the CView
// derived classes.

extern "C" {
        void GLSetupRC(void *pData);
        void GLRenderScene(void *pData);
        void GLResize(GLsizei h, GLsizei w);

The GLSetupRC function is where we will place any code that does initialization for our rendering context. This may be as simple as setting the clear color, or as complex as establishing our lighting conditions. The GLRenderScene function will be called by the OnDraw member function of our CView derived class to do the actual rendering. Finally, GLResize will be called by the WM_SIZE handler, passing the new width and height of the window client area. Here you can do any necessary recalculations to establish the viewing volume and viewport.

Notice that the GLSetupRC and GLRenderScene functions take void pointers. This allows you to pass data of any type to your rendering code without changing the interface. Although we could have made the glcode file a C++ file instead of a C file, it’s easier to move existing C code from any source and include it in the MFC program. Visual C++ will just compile this module as a C file and link it into the rest of the application.

We don’t present the glcode.c file here because the code for our sample is quite lengthy, but you can browse it from the CD to gain general familiarity. Also, we’ll reuse the same file for our OWL sample in the next chapter.

Starting with AppWizard

Many an application written with Visual C++ started life with the AppWizard. The document-view architecture can be compared favorably to the model-view architecture of other object-oriented programming environments. Even for quick-and-dirty applications or experimental projects, the AppWizard can provide a fully functional SDI (Single Document Interface), MDI (Multiple Document Interface), or dialog-based application shell in less than a minute. It makes sense to start here, building a sample SDI MFC application that uses OpenGL. To create a sample OpenGL scene, we’ll add features and functionality to the CView class. You can use the same methods to add OpenGL functionality to any CWnd-derived class.

Previous Table of Contents Next