The first phase of my project to take a DirectX demo to a MID begins with porting DirectX code to OpenGL. In the past several weeks I have spent a lot of time preparing for this phase. I’ve read about half of the OpenGL Programming Guide, often called the “Redbook”, and spent a significant amount of time examining the code for the demo I am porting. I was a little uncertain exactly where to start the porting process, but began at the start of the program. This is a fairly complex, interactive demo with a substantial amount of code. Just the entry point code is unbelievably mired in DirectX variable types and functions. There are also Windows specific functions which I’m not using as this project is intended to run on Linux-based OSs. So all of that has to be eliminated or replaced with standard C or C++ code and/or OpenGL variables and functions. The process wouldn’t be that hard if there was a one-to-one relationship between DirectX and OpenGL. Of course, that isn’t the case. Now, I’m not an expert in either DirectX or OpenGL, so there may be better ways to accomplish my tasks. Feel free to comment and let me know any shortcut or work-around you may have found.
Take the first DirectX element I came to in the code: D3DXVECTOR2. This should be a fairly easy transistion, right? Just replace it with the OpenGL variable and move on. Hmmm….I wish it was that easy. You see, OpenGL doesn’t really have special variables for vectors. OpenGL has commands, glVertex2f, glVertex2i, etc, that are used inside another set of commands, glBegin() and glEnd() to form a primative. But they won’t work as stand alone variables. So, to replace D3DXVECTOR2 you use a GLfloat array, such as this:
You could create your own struct which has two floats( or 3 or 4) and use the structs instead. That is perfectly acceptable. It really doesn’t alter the fact that the coder has to break down the DirectX variables into their basic types. In some cases that is fairly easy, as in the example shown above. But in other cases the methods used vary so greatly that there isn’t a reliable substitute. There is a whole interface in DirectX that is used to manipulate various resources: IDirect3DResource9. The code I am porting from creates a pointer to this interface type, like this:
There are no texture variables in OpenGL. If you look at the references for this interface in DirectX, there are a lot of associated methods that help the developer achieve the look they want. OpenGL also has methods to help the developer, but they aren’t all packaged up together as they are in DirectX.
Try this variable: CDXUTDialog from the DX Utility Toolkit. There are no dialogs in OpenGL, and there aren’t any in GL Utility Toolkit either. Yes, there are sub-windows, but even using sub-windows you don’t have any of the typical control elements you might expect to find, such as buttons, text boxes and entry boxes. To display a menu box, I found a user interface library called GLUI which does have many of the control devices you might need. There are other libraries available. I looked at several of them, and chose GLUI based on three factors: First, it had most of the controls that I wanted to use ; Second, it was most recently updated, indicating that there was still some interest in improving the code and keeping it updated; Third, it has a clearly indicated license. I can’t speak for others, but I have spent way too much time searching for a license for some bit of code I used when working on the release of a project. Now before I use code from another source I make sure I have the license information. But, I digress. GLUI does a fairly good job. It works well with GLUT and that makes my life easier. The menu is not as “pretty” as the original menu, but it has the essential control elements and it interacts well with the main window. You can see a picture of my GLUI menu beside the original DirectX menu below. Several of the original controls have been removed because they were deemed un-needed for the new application.
The next step in the porting process deals with models and meshes. DirectX uses a file format with the extension “.x”. I would like to use these same models if I can, but wasn’t sure about how to go about loading a .x file into my OpenGL program. What I ended up doing was writing a script in Perl that would convert a .x file into a .obj file. There are several different implementations available to open an .obj file in a OpenGL program. I took what I considered to be the best of them and incorporated it into my code (carefully checking the license information first!). Although the imported code read in the vertex information, it didn’t handle any of the material information in the .obj file, so I modified it to be able to load the material information as well. Finally, I wrote an additional function to draw the object on the OpenGL screen. In the process I have found and fixed two bugs in the original code and sorted the faces from the .obj file by the material type they use. That last is to reduce the number of times that glBegin() and glEnd() need to be called. So far, the code is working for objects having only one material. Which seems to indicate that my sorting material code isn’t helping. Well, more on that in my next blog. I’ve been sitting on this one for a while, so I want to go ahead and post this. I should be back soon with some more insights. Until then…