"making something cool with opengl"
Our first assignment for cs140 was to "make
something cool with opengl". As far as I could tell, the intention of the
assignment was to get us used to working with a mainstream graphics library.
I already knew Opengl pretty well, so I took the assignment as a license to
spend some time familiarizing myself with a couple of other libraries that
seemed like they might be useful in later class assignments. As I general
theme for my work, I took particle emitters, something which I had spent a
little time working on before the start of the semester.
I expected that we might implement some filters later in the semester, and
I thought it might be nice to write them as extensions to The GIMP. I had
some limited success in the course of experiments with Gimp, and ended up
creating a little plugin that forces
the alpha channel of an image to be equal to its luminosity (which is handy
if you want bitmap particle images to blend well). Here is a more
detailed writeup of my exploits.
But what I am really proud of is my particle emitter design program. Prior
to the semester, I had spent a few hours trying to design particle emitters.
At that time I was hardcoding the parameters of any given emitter into my
programs, so every time I wanted to see the effect of varying an emitter's
parameter I needed to recompile the whole program. This got to be tedious.
It became clear that what I needed was an interactive program that would allow
me experiment with an emitter's parameters in real time. Using such a program,
I could tweak the parameters of my emitter until I got the effect I wanted,
and then save the result to a emitter info file.
Building this kind of “particle tweaking” utility was obviously going to require
a lot of GUI programing. I took that as an excuse to spend some time learning
the wxWindows library. wxWindows is
a cross platform GUI library, and provides support for OpenGL, (I was using
Opengl to render my emitters, so Opengl support was key to the whole project).
I had heard a little about wxWindows prior to starting this project, but never
really tried using it. Just getting the Opengl sample programs to compile
took a bit of work; I needed to recompile the whole library after changing
some preprocessor flags. In order to create new wxWindows programs using MSVC,
I installed Bill
Nalen's wxWinWizard. Then I built my program by hacking the source for
one of the opengl example programs that I found in the wxWindows sample directory.
Now that I have spent some time working with wxWindows, I can say that I really
like the design of the API, and I plan to use it in later assignments.
So what does the program actually do?
There are a lot of ways that one might design a particle emitter. My origional
idea for the program was that that the user would pick a “particle swarm template”
which would have some set of associated editable parameters. However, because
of my run in with a nasty virus just before the project due date, only the
simplist of those templates was ever implemented. My standard particle emitter
template makes the following assumptions about emitter behavior:
The particles are drawn in a 2d context, so particle direction, velocity,
and force values can all be specified as 2-vectors. Every refresh cycle, the
emitter spits out some number of particles. Those particles are placed at
the emitter center point (given a little random jitter). The particles have
an initial speed and a random direction evenly distributed between 0 and 360
degrees. Every particle is accelerated each refresh cycle. All particles have
some maximum age, and they are destroyed once they hit that age.
Particles are drawn as texture mapped square polygons (the textures have an
alpha channel which can be used to help the particles blend together well).
Each particle's color is a function of its normalized age. To define the color
function I use a set of color points positioned between 0.0 and 1.0, and then
do some linear interpolation to figure out the color of any particle based
on its normalized age. Those color points, as well as the texture, are both
considered parameters of the emitter.
While creating dialogs to edit the numerical parameters was fairly straight
forward, making an interface to edit the color function was a little trickier.
Texture bitmap selection presented a special problem, as wxWindows doesn't
offer support for loading 4 channel image formats. I ended up hacking together
something using SGI's Image Format Library that let me use IFL to load wxBitmaps.
Here is a screen shot of the whole system in action:
Naturally there are many ways in which an emitter's behavior is limited by
all my assumptions, but within the bounds that I have set, I can get a reasonably
diverse set of effects by tweaking the available parameters. And now that
I am familiar with wxWindows, when I find myself needing a particle swarm
with a behavior that can't be expressed within the bounds of the standard
emitter template, I can pretty easily create a new template and extend my
particle design utility to allow for emitters of that type.
All in all I am rather pleased with the program, though I had hoped to take
it a little farther than time allowed. It would have been nice to add a template
for a 3d swarm or allow for more sophisticated particle behaviors. The way
things are now, I am limited to only making emitters that look sortof like
commets or smoke trails. While I did mannage to implement batch printing,
there are some strange bugs that come up if you resize the window and then
try to print.
Here are some (rather large) animated gifs created using the batch print command
along with ImageMagik.
An NPR-ish sun
Your standard commet-like
As much as I would like to keep playing around with these particles, any further
work on this project will probably need to be postponed until after graduation.
Here is source code for my program, as well
as my own closely related particle.h header, and
a compiled binary. The program requires SGI's
Image Format Library (here is
a link to the library installer). The source is still a little rough around
the edges (read "mostly uncommented"). If you want to compile the
program yourself, grab this snapshot
of my dev directory, install all the relevant
libraries, and unzip the contents of the binary zip file in dev/src/wx_ptweak.
Then you should be able to build everything from MSVC6 using the wx_ptweak
workspace. (If you try to compile the code, you may notice that I am not linking
to my own static libraries, but instead building straight from the library
sources; this is messy, but I seem to need to do it because of conflicts between
STL and wxWindows.)
Cut out the directx dependencies (there is really no good reason for them
to be there).
Add in a lightning template using the model from that sigraph
paper that Daniel presented.
And, of course, comment and doxygenitize
all the code. :)