libgfx: OpenGL Support
Author: Michael Garland

## OpenGL Support

Important: The standard way to include the OpenGL headers is to include the headers

        #include <GL/gl.h>
        #include <GL/glu.h>

However, to ensure portability you should not do this; use the following inclusion instead:

        #include <gfx/gl.h>

The primary reason for this is that the Microsoft OpenGL headers do not work properly unless you have included `<windows.h>` first. This `libgfx` header takes care of the necessary `#ifdefs` and keeps your code looking cleaner.

### Utility Functions

To gain access to these utility functions, include the header

        #include <gfx/gltools.h>

Given a pixel coordinate in the OpenGL viewport, it is often necessary to project this to a 3-D point in the world being displayed. You can use the function

        int unproject_pixel(int *pixel, double *world, double z=0.0);

to accomplish this.

To simplify the display of 3-D scenes, the function

        void camera_lookat(const Vec3& min, const Vec3& max, double aspect);

will set up a standard viewing geometry for displaying an object bounded by the axis-aligned box [`min`, `max`] in a window whose aspect ratio is `aspect`. The camera will be looking at the center of the box, from a position further along the z axis, with a 60° field of view. The viewing transform will be multiplied into the current matrix, using calls to `gluPerspective()` and `gluLookAt()`.

Errors during OpenGL processing are not reported to the user, they are merely flagged in the current OpenGL state. To check for and report any OpenGL errors, you can call the function:

        void check_opengl_errors(const char *msg=NULL);

An optional message can be provided which will be prepended to the error reported (if any).

#### Picking

Interactive programs frequently need to allow the user to select individual components of the scene being displayed by clicking on the rendered image. Given a pixel location in the window, the application must determine which entity the user clicked on. The standard technique for doing this with OpenGL is with the selection buffer. The `libgfx` library provides some utility functions to make using the selection buffer somewhat easier. Details on using the selection buffer can be found in the OpenGL Programming Guide.

Before drawing your primitives, call the function

        void begin_opengl_pick(int *ctr, double radius, GLuint *buf, int size);

with the location of the user's pointer (`ctr`) and the `radius` of the region to consider. You will also need to allocate and pass a buffer of object identifiers to hold the candidate objects. Having set things up, you can draw your primitives as usual, assigning an integer identifier to each using the `glLoadName()` function. After all primitives have been drawn, call the function

        GLuint complete_opengl_pick(GLuint *buffer);

The returned value will be the identifier of the object clicked on, or `opengl_pick_nil` if the user clicked on the background.