As mentioned in the introduction of this section, there are times when you want to take advantage of a known behavior in a particular implementation. If you know for a fact that you are using Microsoft’s rendering engine, and the version number is the same as what you tested your program with, it’s not unusual that you’ll want to try some trick to enhance your program’s performance. To be sure that the functionality you’re exploiting exists on the machine running your program, you need a way to query OpenGL for the vendor and version number of the rendering engine. Both the GL library and GLU library can return version and vendor specific information about themselves.
For the GL library, you can call glGetString:
const GLubyte *glGetString(GLenum name);
This function returns a static string describing the requested aspect of the GL library. The valid parameter values are listed under glGetString in the Reference Section, along with the aspect of the GL library they represent.
The GLU library has a corresponding function, gluGetString:
const GLubyte *gluGetString(GLenum name);
It returns a string describing the requested aspect of the GLU library. The valid parameters are listed under gluGetString in the Reference Section, along with the aspect of the GLU library they represent.
Listing 5-2 is a section of code from the GLTELL sample program, a modified version of our faithful bouncing square. This time we’ve added a menu and an About box. The About box, shown earlier in Figure 5-1, displays information about the vendor and version of both the GL and GLU libraries. In addition, we’ve added an error to the code to produce a listing of error messages.
Listing 5-2 Example usage of glGetString an gluGetString
// glGetString demo SetDlgItemText(hDlg,IDC_OPENGL_VENDOR,glGetString(GL_VENDOR)); SetDlgItemText(hDlg,IDC_OPENGL_RENDERER,glGetString(GL_RENDERER)); SetDlgItemText(hDlg,IDC_OPENGL_VERSION,glGetString(GL_VERSION)); SetDlgItemText(hDlg,IDC_OPENGL_EXTENSIONS,glGetString(GL_EXTENSIONS)); // gluGetString demo SetDlgItemText(hDlg,IDC_GLU_VERSION,gluGetString(GLU_VERSION)); SetDlgItemText(hDlg,IDC_GLU_EXTENSIONS,gluGetString(GLU_EXTENSIONS));
Take special note of the GL_EXTENSIONS and/or GLU_EXTENSIONS flags. Some vendors (including Microsoft, with the latest versions of OpenGL) may add extensions to OpenGL that offer vendor-specific optimizations, or popular OpenGL extensions that aren’t yet part of the standard. These features can enhance your performance considerably. If you make use of these extension functions, however, you must test for the presence of the extensions (using GL_EXTENSIONS); and if they are not present, you must implement the feature by some other means.
The list of extensions returned will contain spaces between each entry. You will have to parse the string yourself to test for the presence of a particular extension library. For more information on OpenGL extensions, see the wglGetProcAddress function (Chapter 4), or your specific vendor’s documentation. The Microsoft extensions are discussed and demonstrated in Appendix A.
We have mentioned taking advantage of known anomalies in the OpenGL libraries. You can exploit other vendor-specific behaviors, as well. For one thing, you may want to perform renderings as quickly as possible on a generic implementation, but switch to a more accurate view for hardware-assisted implementations. Even without the vendor dependencies, you may simply want OpenGL to be a little less picky for the sake of speed—or to be more fastidious and produce a better image, no matter how long it takes.
The function glHint allows you to specify certain preferences of quality or speed for different types of operations. The function is defined as follows:
void glHint(GLenum target, GLenum mode );
The target parameter allows you to specify types of behavior you want to modify. These values, listed under glHint in the Reference Section, include hints for fog and anti-aliasing accuracy. The mode parameter tells OpenGL what you care most about—fastest render time and nicest output, for instance—or that you don’t care. An example use might be rendering into a small preview window with lower accuracy to get a faster preview image, saving the higher accuracy and qualities for final output. Enumerated values for mode are also listed under glHint in the Reference Section.
For a demonstration of these settings on various images, see the supplementary sample program WINHINT in this chapter’s subdirectory on the CD.
Bear in mind that not all implementations are required to support glHint, other than accepting input and not generating an error. This means your version of OpenGL may ignore any or all of these requests.
Even in an imperfect world, we can at least check for error conditions and possibly take action based on them. We can also determine vender and version information so that we can take advantage of known capabilities or watch out for known deficiencies. This chapter has shown you how to marshal your forces against these problems. You’ve also seen how you can ask OpenGL to prefer speed or quality in some types of operations. Again, this depends on the vendor and implementation details of your version of OpenGL.