AmigaMesaRTL 2.0 A run-time library of Mesa 2.6 by Jarno van der Linden jarno@kcbbs.gen.nz http://www.kcbbs.gen.nz/~jarno/AmigaMesaRTL.html Mesa 2.6 is Copyright (C) 1995-1998 Brian Paul INTRODUCTION ============ Once upon a time there was an Amiga port of Mesa by Stefan Zivkovic. However, just as this port became interesting, Stefan could no longer support it. Then came CyberGL. A run-time library, which ran reasonably comfortably even on lower-end machines with AGA. Unfortunately, it only implemented a subset of OpenGL. Furthermore, the output even on a 256 colour AGA screen was far from impressive. At present, development seems to have stalled (possibly pending the release of the 3D drivers for the CV-PPC and BVision cards). Back to Mesa, through H&P we've seen the release of StormMesa. Unfortunately this too comes in the form of a link library. (Although that is soon to change I gather). So I set out to create my own driver with the following objectives: - Based on the latest release of Mesa - Should come in the form of a run-time library - Reasonable speed on an 50MHz '030/'881 system - Good quality output on AGA With AmigaMesaRTL, I think I have achieved these goals. Of course, don't expect miracles. Framerates are still better counted in seconds-per-frame rather than frames-per-second on my machine (A1200, Blizzard1230IV, 50MHz '030/'881, 32MB fast). But it is still faster than CyberGL and the output is a significantly better. THEORY OF OPERATION =================== The main Mesa functions (such as glBegin(), glFlush(), etc. etc. etc.) are in mesamain.library. These functions do all sorts of things, and eventually call some driver functions to handle the platform-specific output. The driver (amigamesertl.c) does all reading from and writing to a simple memory buffer. This buffer is made up out of single bytes in the case of colour index mode, and 4 bytes in the case RGB or RGBA mode. When glFlush() is called, the buffer is processed by an Output Handler. The traditional thing for an output handler to do is to quantize the buffer to a displayable number of colours, and C2P the buffer to a window. Output handlers can however do many other things, such as send the buffer directly to an image editing program (e.g. ImageFX using the magic.library). What output handler to use depends on the output type specified by the application. For example, if the output type is "Window", the output handler specified by the environment variable "AmigaMesaRTL/Window" is used. The default output handler is a slightly modified version of DL1 from a package by Dennis Lee (denlee@ecf.utoronto.ca). I've included the original documentation in the amiga/outputhandlers/dl1 directory. Because of the various buffers involved, AmigaMesaRTL does use a fair bit of memory. COMPILING THE LIBRARY ===================== The AmigaMesaRTL distribution only contains the changed and new files of Mesa. You will need the Mesa 2.6 distribution. Once you have obtained the Mesa 2.6 distribution and unpacked it to somewhere, copy the amiga directory of AmigaMesaRTL to the Mesa directory. Go to the amiga/src directory, change the SCOPTIONS file to suit your system (mainly the MATH and CPU settings), and run SMake. Sit back, relax, enjoy life. This is going to take a while. Note that there are still a few references to __XCEXIT(). Just ignore it and let the linker replace it with __stub(). Once this is done, you should end up with a file called mesamain.library in the amiga/library directory. Go to the amiga/drivers/amigamesartl directory, edit SCOPTIONS, run SMake. Out pops amiga/mesadrivers/amigamesartl (no ".library"). Some output handlers can be found in amiga/outputhandlers. Go to one of them (e.g. dl1), edit SCOPTIONS, run SMake, and you should now have a library called amiga/library/outputhandlers/dl1. The GLUT library is made by going to amiga/src-glut, edit SCOPTIONS, SMake, and you have amiga/library/glut.library. Finally, go to the amiga/lib directory, edit the SCOPTIONS file if you want to, run SMake. Out should come Mesa.LIB and GLUT.LIB. That is all that is needed to get a working mesa library. Whew! Alternatively, edit all the SCOPTIONS files you can find to suit your system and execute mklib.amiga. USING THE LIBRARY ================= To compile a program using AmigaMesaRTL, make sure the compiler can see the files in amiga/include and the link libraries in amiga/lib (by e.g. adding them to your INCLUDE: tree). Mesa.LIB contains autoopen code for the mesamain.library, so you shouldn't have to worry about opening and closing it. Just don't forget to link with Mesa.LIB. It will also cause a driver library to open. If you want to open the libraries yourself, I recommend opening mesamain.library, and then getting a driver library base from it by calling mesaGetAttr(MESA_DriverBase,&mesadriverBase). It is also possible to open a specific driver, see the mesadriver and mesamain docs. In typical use, you probably want to output the result to a window. After setting up your Intuition window as per usual, create a context for it by calling AmigaMesaRTLCreateContext(). Pass a pointer to the window to the output handler with OH_Output, and tell it is a window by setting OH_OutputType to "Window". Make sure the context is current by calling AmigaMesaRTLMakeCurrent(). Do lots of interesting graphics stuff. Don't forget that glFlush() has to be called (directly or indirectly) for the result to be send to an output handler. Before closing the window, you should destroy the context with AmigaMesaRTLDestroyContext(). For example (without error checking): my_window = OpenWindowTags(...); my_context = AmigaMesaRTLCreateContext( OH_OutputType, "Window, /* Output is a window */ OH_Output, my_window, /* Use my window */ AMRTL_RGBAMode, TRUE, /* RGBA drawing mode */ TAG_END); AmigaMesaRTLMakeCurrent(my_context); /* ...Do OpenGL stuff... */ AmigaMesaRTLDestroyContext(my_context); CloseWindow(my_window); See the included examples and src-glut/glutCreateWindow.c for inspiration, and the mesadriver and outputhandler docs. GLUT ==== Having a Mesa library is all fine and dandy, but most Mesa and OpenGL examples use the GL Utility Toolkit (GLUT) by Mark Kilgard. So the obvious answer is: we need a port of GLUT. Having looked at the GLUT source code, this is easier said than done. It is highly X11-centric, with a Windows port mixed in. I thought about it, but in the end I decided to do a from-scratch GLUT look-alike implementation. It can be found in amiga/src-glut. At present, most of the most-commonly used functions are implemented. No guarantee that they behave identically to the official GLUT distribution, but most of the redbook examples seem to work OK. Using GLUT ---------- when compiling a GLUT program, make sure you link with GLUT.LIB and Mesa.LIB. These will open the libraries for you. If you want to open the GLUT library yourself, you must remember to tell GLUT which mesamain base and mesadriver base to use by calling glutAssociateGL(). These bases should be the same ones the application is using. When run, a glut program will by default let the output handler open a window. If told top open a window itself, GLUT will try to open a window on a public screen named Mesa, or the one specified by the pubscreen argument. Use one of the zillion pubscreen managers available on AmiNet to set up a public screen. GLUT Menus .......... The GLUT menus use the usual Amiga menu system. Instead of having a menu associated with a mouse button, there is a "Left Menu", "Middle Menu", and "Right Menu" menu. As the Amiga menu system only supports up to one level of sub-menus, any sub-sub-menus (and sub-sub-sub-menus and sub-sub-sub-sub-menus and ...) will be changed to a sub-menu after the parent. GLUT mouse buttons .................. As the right mouse button is tied up with menus, middle and right mouse button presses can be done by qualifying the left mouse button press with the Right-Amiga and Right-Alt keys respectively. For those of you with three-button mice, the middle button should also be recognised. GLUT termination ................ The GLUT main loop is traditionally terminated by exit()'ing the program. Amiga GLUT uses SAS/C's STI_ and STD_ mechanism to clean up on exit(). Quiting a GLUT program is usually done by pressing the ESC key. Clicking the window close button will cause Amiga GLUT to call the context's keyboard function with an ESC key code. However, some example programs never exit. Instead they expect the user to kill the program (by e.g. ^C). To handle such evil programs, Amiga GLUT has a panic drop-through. If pressing the window close button has no effect (i.e. the program is not listening to ESC key presses), a second click on the window close button will cause glutMainLoop() to return. This usually works as glutMainLoop() is often the last command in main() before it returns. But, as this is against the documented behaviour of glutMainLoop(), Bad Things may happen instead. As of version 2, the GLUT library also listens for ^C. When received, this too causes glutMainLoop() to return. This is handy in case the window doesn't have a close gadget. GLUT keys ......... The GLUT special keys implemented are: the cursor keys, and functon keys F1 to F10. Idle .... A single glutMainLoop() loop will handle all the messages on the queue. If set, glutIdleFunc() will be called whenever glutMainLoop() finds no messages to handle (other than IDCMP_INTUITICKS) in a single loop. (This is in contrast to a macintosh implementation I know of which actually speeds up if you e.g. press a key). Running a GLUT program ---------------------- Any GLUT program which calls glutInit() (as all should), recognises the following command line options: Option : -pubscreen Values : Default : Mesa Description : Set the public screen to open windows on Option : -outputhandler Values : Default : Description : Set value for AMRTL_OutputHandler Option : -outputhandlerversion Values : Default : Description : Set value for AMRTL_OutputHandlerVersion Option : -nohandlerwindow Values : Default : Description : When specified, don't let the output handler open a window. GLUT will open a window instead. If a program doesn't appear to give any output, check to see if it calls glFlush(), or anything that calls it (like glutSwapBuffers()). If it doesn't, add it (typically at the end of the display() function). Also make sure you give the program plenty of stack. WARNING! -------- Please beware that at present, Amiga GLUT lacks a lot of error checking. Bad Things will very likely happen if Something Goes Wrong. ENVIRONMENT VARIABLES ===================== From v2, a variety of environment variables are used by AmigaMesaRTL. Here is a summary. The effect of a variable can be limited to one program by setting a local environment variable, or made general by setting it as a global environment variable. The values of each of these variables can of course be overridden by an application by setting tag values. AmigaMesaRTL/Driver (default: amigamesartl) AmigaMesaRTL/DriverVersion (default: 2) -------------------------- Name and version of driver to use. A driver with the exact name given is expected to be found in LIBS:MesaDrivers/. AmigaMesaRTL/OutputHandler (default: dl1) AmigaMesaRTL/OutputHandlerVersion (default: 2) --------------------------------- Name and version of output handler to use. An output handler with the exact name given is expected to be found in LIBS:OutputHandlers/. AmigaMesaRTL/ (e.g. AmigaMesaRTL/Window) -------------------------- Name of the output handler to use for a specific output type. This overrides the AmigaMesaRTL/OutputHandler variable. An output handler with the exact name given is expected to be found in LIBS:OutputHandlers/. AmigaMesaRTL/.prefs (e.g. AmigaMesaRTL/dl1.prefs) ----------------------------------- Each output handler can have its own preferences. These are stored in this environment variable. The format is output handler specific, but should be parseable by ReadArgs() using the pattern obtained by getting the value of OH_ParameterQuery from the output handler. MORE DOCUMENTATION ================== Autodoc-style documentation is provided in amiga/drivers/mesadriver.doc, amiga/outputhandlers/outputhandler.doc, and amiga/src/mesamain.doc. FUTURE ====== Mesa 3.0 will shortly emerge from beta state. It shouldn't take long for me update the library to it when it does.