This is a specialized class to provide very basic support for the OpenGL graphics package. Unlike other V canvas panes, this class does not use a vDC class. Instead, it has a few features designed to support OpenGL.
This is a basic class. It does not provide many convenience methods to support OpenGL at a high level, but it does hide all the messy details of interfacing with the host GUI environment, and provides the first really easy way to generate sophisticated interfaces for OpenGL applications. A more sophisticated class called vGLCanvasPane that will provide a number of convenience operations is under development, but the base class is still very useful.
By following a standard convention to structure V/OpenGL code, it is relatively easy to generate applications. The details of this convention are explained in the tutorial section of this description.
See the section vPane for a general description of panes.
V supports only one visual per application, and the first vBaseGLCanvasPane created determines the attributes of the visual used.
The following methods provide useful service without modification. Sometimes you will want to override some of these, but you will then usually call these methods from your derived class. Most of these methods are the equivalent of the normal V vCanvasPane class.
It is important to remember that all mouse coordinates are in screen pixels, and use 0,0 as the upper left corner. You will probably have to map them to the actual coordinates in use by your OpenGL graphic.
See the description of vCanvasPane for details.
The parameters of Redraw represent the rectangular area that needs to be repainted. This areas is not always the whole canvas, and it is possible that many Redraw events will be generated in a row as the user drags a covering window off the canvas.
The default Redraw in vBaseGLCanvasPane is a no-op, and your subclass needs to override Redraw.
The default Resize in vBaseGLCanvasPane is a no-op, and your subclass needs to override Redraw.
It is critical that you call the graphicsInit method in the base vBaseGLCanvasPane class first, then whatever OpenGL calls you need. See the example in the OpenGL tutorial section for more details.
A minimal V/OpenGL application will consist of a class derived from vApp, a class derived from vCmdWindow, and a canvas pane class derived from vBaseGLCanvasPane. Most of your drawing code will be in or called from your derived canvas pane.
Within that class, you will minimally need to override the graphicsInit method, and the Redraw method. The following code fragment, adapted directly from the example code in Mark J. Kilgard's book, OpenGL, Programming for the X Window System, shows how simple it can be to draw a picture. The full code can be found in the opengl/shapes directory in the V distribution.
static int initDone = 0;
......
//==========>>> testGLCanvasPane::graphicsInit <<<=================
void testGLCanvasPane::graphicsInit(void)
{
// Always call the superclass first!
vBaseGLCanvasPane::graphicsInit();
// Example from Mark Kilgard
glEnable(GL_DEPTH_TEST);
glClearDepth(1.0);
glClearColor(0.0, 0.0, 0.0, 0.0); /* clear to black */
glMatrixMode(GL_PROJECTION);
gluPerspective(40.0, 1.0, 10.0, 200.0);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0, 0.0, -50.0);
glRotatef(-58.0, 0.0, 1.0, 0.0);
initDone = 1;
}
//============>>> testGLCanvasPane::Spin <<<=======================
void testGLCanvasPane::Spin()
{
// Called from the parent CmdWindow for animation
vglMakeCurrent(); // Call this FIRST!
glRotatef(2.5, 1.0, 0.0, 0.0);
Redraw(0,0,0,0);
}
//============>>> testGLCanvasPane::Redraw <<<=====================
void testGLCanvasPane::Redraw(int x, int y, int w, int h)
{
static int inRedraw = 0;
if (inRedraw || !initDone) // Don't draw until initialized
return;
inRedraw = 1; // Don't allow recursive redraws.
vglMakeCurrent(); // Call this to make current
// Code taken directly from Mark J. Kilgard's example
// Draws 3 intersecting triangular planes
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_POLYGON);
glColor3f(0.0, 0.0, 0.0); glVertex3f(-10.0, -10.0, 0.0);
glColor3f(0.7, 0.7, 0.7); glVertex3f(10.0, -10.0, 0.0);
glColor3f(1.0, 1.0, 1.0); glVertex3f(-10.0, 10.0, 0.0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 0.0); glVertex3f(0.0, -10.0, -10.0);
glColor3f(0.0, 1.0, 0.7); glVertex3f(0.0, -10.0, 10.0);
glColor3f(0.0, 0.0, 1.0); glVertex3f(0.0, 5.0, -10.0);
glEnd();
glBegin(GL_POLYGON);
glColor3f(1.0, 1.0, 0.0); glVertex3f(-10.0, 6.0, 4.0);
glColor3f(1.0, 0.0, 1.0); glVertex3f(-10.0, 3.0, 4.0);
glColor3f(0.0, 0.0, 1.0); glVertex3f(4.0, -9.0, -10.0);
glColor3f(1.0, 0.0, 1.0); glVertex3f(4.0, -6.0, -10.0);
glEnd();
vglFlush(); // Call when done drawing to display
inRedraw = 0; // Not in here any more
}
....
Note that this example includes a method called Spin.
It is used to animate the intersecting planes. In a
V
OpenGL application, the easiest way to implement animation
is with the timer. Create a timer in the Command Window
class, and then call the animation code in the canvas
in response to timer events. You should keep code to
prevent recursive redraws if the timer events end up
occurring faster than the picture can be rendered, which
might happen for complex pictures or heavily loaded systems.
See the example code in the v/opengl directory for
a complete example of animation using the timer.
You should be able to include regular V Canvases in your application, as well as OpenGL canvases. In versions before 1.20, the OpenGl canvas was a replacement for the standard vCanvasPane. It is now properly derived from vCanvasPane.
I've tried to make the OpenGL canvas easy to use. The best way (for now) to learn how to use the class is to look at the sample programs included here. To use it, compile your code, and link it with the V library and the V OpenGL library.
This version has been tested on Linux with Mesa 2.6. It used to run on Silicon Graphics machines, and there is no reason to assume that has changed.
When I installed Mesa, I had to add some symbolic links to have it link like standard OpenGL, but you could also change the library switches in the Makefiles.
There are a several of samples, some derived from GLUT, others from the Mesa distribution. Each sample is included in a separate directory. There are mingw32 makefiles for MS-Windows for all examples, and Linux makefiles for many.
This documentation for vBaseGLCanvasPane is still incomplete. The best way to use it is to look at <v/vbglcnv.h> and the examples. I've only been able to get the Windows version to work correctly under mingw32 and Borland C++ 5.0. Microsoft C++ 4.0 couldn't find the proper link libraries. If someone knows how to get this problem solved, please let me know.
The Mingw32 distribution requires proper .h files. They are included in the gnuwin32 directory. The OpenGL header files I provide are edited to remove references to CALLBACK parameters, which means the tessellation stuff doesn't work.
The Windows version doesn't seem to support Indexed color mode, even though the definitions are there, and some code looks like it generates a correct graphics context. The problem for now seems to be there is no equivalent of glutSetColor to set a color index. Does ANYONE in the whole world actually use Indexed color? If so, then I'll look at glut and see if I can add indexed color support.
I am working on developing a new vOpenGLCanvasPane class with a V user. The new class will have built in support for some vector stuff and some lighting stuff. Would anyone like some of the glut shapes: spheres, cubes, etc? They shouldn't be too hard to add, but I don't know if they really get used.