phase 11:
integration with OpenGLoverview
the goal of this assignment was, broadly, to do something cool using OpenGL. I focused on integrating OpenGL into the graphicsDeploy system, enabling both hardware rendering from within graphicsDeploy and model export/import functions to export models from graphicsDeploy for use by other applications which use OpenGL. see the deployGL.h, deployGL_export.h, and deployGL_import.h sections of the api for interface details.
deployGL hardware renderer
the system now has the option of doing its actual drawing with a hardware renderer using OpenGL rather than the software rendering of graphicsDeploy (hereafter referred to as the deploy renderer). higher level modelling and rendering functionality is still controlled by graphicsDeploy, but when it comes time to draw triangles, the system can either use the OpenGL render or the deploy renderer (ie. the draw3d.c code).
sadly, not all features available in graphicsDeploy are supported by OpenGL, specifically shadow rays and phong shading, and certain features just look better using the deploy renderer, such as transparency. consequently, the client has the option to explicitly activate or deactive hardware rendering. alternatively, a 'dynamic' option (the default) is available, which only activates hardware rendering if not using phong shading or shadows.
of course, the benefit to hardware rendering is the gain in rendering speed. rendering 46 frames of the book animation takes 4.3 seconds using hardware rendering, as opposed to 9.0 seconds using the deploy renderer (and you should keep in mind that much of that time is software overhead common to both).
the images on the left were rendered using OpenGL, those on the right using the deploy renderer; otherwise the scenes are identitcal. for some reason, specularities seem to always come out different with OpenGL -- I could always change my code to more closely match, but I'm still conviced that I'm right, and therefore refuse to change...
transparency using OpenGL
the deploy renderer uses an alpha-buffer to implement transparency, wherein for each pixel a linked list of opacity, color, and depth values is stored (see phase 7). OpenGL doesn't really support that; granted, one could probably do something fancy with the accumulation buffer, but I decided to just pre-sort the triangles by depth, then draw them into the image (drawing the triangle furthest from the viewer first); triangles are drawn using alpha-blending. this works fairly well, but will not work in the case of intersecting triangles. also, there is a performance hit for doing the depth sort.
in the images below, the two on the left were drawn using OpenGL and the one on the right was drawn using the deploy renderer; leaf positions aside, the scenes are identical. in the image on the far left, the triangles were not sorted before being drawn (this is not actually a feature supported by the system, but I include the image to serve as an example of why depth-sorting is important). in the middle image, there are a couple problem areas evident in the vase, which might result from the water triangles sitting close to the vase triangles (again, this problem does not occur in the deploy rendering).
the following images demonstrate the problems this method of drawing transparency encounters with intersecting triangles -- the image on the left is drawn using OpenGL, the one on the right with the deploy renderer.
exporting and importing with deployGL
I created a sort of ad-hoc ".dgl" file format (for deployGL), which specifies scene characteristics (background, lighting), line and triangle vertex positions (with normals and texture coords attached to triangle vertices), and material properties. The user of the deploy system may make calls to export_scene(), export_frame(), and export_batch(), which are all analogues to their render_() counterparts. The difference being, after the system has broken everything down into triangles and line segments, rather than actually drawing the elements, the relevant information is just written out into a .dgl file.
.dgl scenes can then be imported using calls to deploy_gl_import() and deploy_gl_import_batch(). both of these return display lists, which can then be called from within an openGL application to display the scene. in the case of batch imports, a series of display lists is created, such that each frame in the animation gets its own display list. keep in mind, this would be foolish if all you wanted to animate was something simple like a translation, rotation, etc., because you could do that straight in openGL, but for something more complex, like the pages of a book turning, it is a nice feature.
both exporting and importing, both with static and animated scenes, has been tested and seems to work. I tested things using a simple glut utility I wrote called deploy_view, which reads in a .dgl file and then displays the scene or animation, allowing the user to view from arbitrary angles by "mousing around".
distortions
just for fun, I decided it was time for distortions, ie. non-linear transformations. these are placed in the hierarchy so that to the user, they seem just like linear transformations. the trick is, with a linear transformation, all you need to do is perform a matrix multiplication every time you encounter a transformation and then just go about your business, and then later on when you actually have to draw something using the accumulated list of applied transformations, that information is implicit in the current transformation. such is not the case for non-linear transformations! we now have to keep explicit track of which non-linear transformations have been executed, and in what order, and what the linear transformations that took place in-between were. this ends up being a fairly straightforward linked list problem, and wasn't too bad...
the distortions implemented thus far are stretch, taper, bulge, flare, wave, bend, twist, and noise.
the following animations, all drawn with OpenGL, demonstrate, in order: taper with animated eccentricity, twist with animated angle, wave and animated stretch, low and high angle bends, and a high-angle bend with animated bend axis.
the following animation, done in the deploy renderer, features a bent and twisted flower.