[SDL] [DEMO] Minimal world engine in SDL+OpenGL

Fabio Giovagnini fgiovag at tin.it
Fri Jan 17 01:15:01 PST 2003

very interesting.
is this software usable under GLP?


Alle 05:59, venerdì 17 gennaio 2003, Daniel Phillips ha scritto:
> Around Christmas I suddenly felt compelled to try out some 3D mathematical
> experiments I've been thinking about for a while, and I needed a simple 3D
> engine to let me visualize the constructions.  I looked around, and though
> I was able to find quite a few systems that would do the job, e.g.,
> Crystalspace, Neoengine and Nebula Device just to name three, I did not
> find anything that came remotely close to meeting my requirement of
> "simple". However, I convinced myself that, by using OpenGL to do the heavy
> lifting of low-level rendering and SDL to take care of device handling, I
> could probably write what I needed in two weeks and a thousand lines or so,
> and still have time left over to partake of some Christmas cheer.
> Well, I'm into overtime by a week, and I came in under a thousand lines
> only if you don't count the headers and demos, but I feel I got close
> enough to meeting my objectives to declare victory at this point, and the
> result has actually proved usable for the purpose intended.  I wish to
> contribute what I've created up to now as a demonstration of some of the
> capabilies of OpenGL and SDL, and of a few useful engine design techniques.
>  Who knows, it's even possible that this could develop into a full blown
> game engine one day.[1]
> Since even a demo needs a name, and I'm not feeling particularly
> imaginative at the moment, I call it "world".  At least nobody can claim
> property rights over that name, not unless the intellectual property regine
> in the U.S. gets a lot more perverse than it already is.[2]  If you need
> some way of distinquishing this particular world from all other possible
> worlds, I suppose its full name is "Daniel's world".
> So what's in it?  Well, not a lot actually, and that's how I wanted it. 
> The purpose of this world is to be as minimal as possible, and not get in
> the way, but still provide a useful framework for the job it is supposed to
> do: visualize 3D models, move around in them, and manipulate them.
> Here are the features:
>  - 3D model viewing, navigation and event processing framework
>  - Resizable OpenGL surface complete with fullscreen mode, courtesy of SDL
>  - Simple model definition interface: empty.c is only 3 lines long
>  - Leaves rendering and physics to the target model
>  - 3D vector library in functional programming style
>  - Generic horizon and infinite ground reference grid
>  - Input event binding system unifies various input devices
>  - Walkaround and flythrough navigation modes
>  - Navigation via mouse and/or keyboard controls
>  - Manipulate world objects with the mouse
>  - Constant rate physics scheduler
>  - Debugger interface
> Pretty bare-bones, which is, once again, the way I want it.  Any fancier
> and it would cease to be a demo.  Still, there are a few niceties worth
> pointing out.  For example, the encapsulation of a world model is succinct.
>  A typical static OpenGL model can be recast as a world model using the
> line:
>    struct world world = { .create = create, .render = render };
> where the former main routine of the model is broken up into a "render"
> part the draws the scene and a "create" part that has the remainder of the
> former main routine, e.g., set up lights, load models, etc.  Any setup of
> projections and viewpoints is ignored and can simply be deleted, since the
> world engine does this in a much more useful way.
> Most OpenGL demos are animations, and it's only a little more work to
> convert these to world models.  The fanciest I've converted so far has an
> interface something like:
>    struct world world =
>    {
> 	.create = load_model,
> 	.render = draw_model,
> 	.motion = step_model,
> 	.button = handle_button,
> 	.filter = filter_SDL_event,
>    };
> The "motion" method provides animation, beyond simple viewpoint motion. 
> This could simply step a time variable or it might be hooked up to a full
> blown physics and collision detect system.  (One of the sample world models
> is a non-trivial mass-spring physics simulation.)
> This method of encapsulating a world model is really just a way of breaking
> up the components of a C program for separate compilation.  However, it's
> not going to stay that way.  I plan to implement a load/unload facility for
> world models, so that they can be recompiled and reloaded without losing
> the state of the engine, including viewpoint and window geometry, which is
> a little luxury I grew used to in the past, and to which I wish to become
> accustomed to once again.
> I converted a few glut-based OpenGL demos to world models as an exercise,
> and they are included in the source.  They all became shorter and, to my
> eyes, more elegant.  I find glut to be a respectable toolkit, but it
> suffers from the fatal flaw of competing with SDL on the one hand and event
> engine frameworks such as mine on the other.  Still, some of glut's library
> routines, e.g., stroke and bitmap text drawing, work perfectly well inside
> my engine, and I have included an example of such usage in the sample
> worlds. Glut's drop-down menus don't work at all, apparently because its
> windowing system has not been initialized.  That's ok - gui widgets are
> planned for implementation in my second thousand lines of code, and I would
> prefer a more generic approach anyway.
> One wrinkle in converting a glut model to a world engine model is the fact
> that glut demos normally treat OpenGL's default viewing direction, down the
> negative Z axis as "forward", but within my framework that is "down".  No
> problem, you will simply see the model sitting below the ground grid, and a
> quick tweak will bring it up into a more sensible (to my mind) southward
> orientation.  Unlike traditional rendering approaches, being able to walk
> around in any model by default completely eliminates the "black screen
> problem", where you don't see any graphics because it happens to be behind
> the camera.  In my world, you just look around until you see where the darn
> thing is.
> I noticed some questions recently on this list about how you would go about
> treating different input devices in a similar way, so that actions can be
> defined abstractly and bound perhaps to more than one input device, or
> moved easily between devices.  This is a capability that should not be
> provided by a library like SDL, but instead be provided at a higher level
> in an engine like this one.  There is a nice example of a minimal but
> nonetheless flexible system for doing exactly that in this engine.  Please
> feel free to borrow the code, after all it is GPL.[3]
> The 3D vector toolkit I've provided deserves mention.  It organized around
> structure value parameters and structure value returns, which allows you to
> write things like:
> float v3intersect_ray_ray(vec3 p1, vec3 v1, vec3 p2, vec3 v2)
> {
> 	vec3 cross = v3cross(v1, v2);
> 	return v3dot(v3cross(v3sub(p2, p1), v2), cross) / v3dot1(cross);
> }
> In other words, you can write vector code in a functional style just as you
> would write scalar math expressions.  So it's very c++-like, except that
> you cannot overload operators, which is probably a blessing in disguise.
> Initially, I implemented the engine with a more traditional style of vector
> math using pointers, which required you to provide storage for function
> results and did not allow vector function cascading as in the above code,
> then I rewrote it all to use the functional style.  GCC generates compact,
> efficient code for the former style, but it's a great inconvenience for
> development, and the resulting source code is, in a word, ugly, not to
> mention hard to read.  In any event, the fact that GCC generates bulky code
> for structure-valued returns and parameters has more to do with the
> relative newness of such features in C; there is no fundamental reason why
> any more code should be required in order to save intermediate structure
> results on the evaluation stack as opposed to elsewhere in the stack frame.
>  And even with this little luxury, the binaries are still coming in very
> small - around 30K for each of the demos.  For code where efficiency is
> critical, you want write out the vector math in full anyway, because there
> are always significant optimizations you can make when you look at the
> details of everything that's going on.
> About ten percent of the engine code is devoted to drawing a single
> polygon: the sky polygon.  It turns out that it is much more difficult to
> draw a sky as a flat shaded polygon, or even a line, than it is to wrap a
> cubical or spherical map texture map around the world.  However, since my
> primary goal is to create a design platform rather than a game engine, I
> did not want a textured sky, and I did not want to see any of those
> distracting texture artifacts on the all-important horizon reference, so I
> did it the hard way.
> The ground grid is somewhat interesting in that it is infinite, and new
> reference lines fade into view as you move.  Whatever, I feel that a design
> platform cannot do without decent ground and sky references, and this
> engine has them.
> As far as I'm concerned, a design platform is also pretty useless if you
> cannot manipulate objects in the world.  As a first cut, I provide the
> ability to treat the mouse pointer as a ray in world coordinates, so that
> you can intersect it with objects and manipulate them.  The "waves" model
> demonstrates this technique, and actually, there's more than a little play
> value there.  (You'll see.)
> Now, the little glitches that came up.  Starting with the time-reversing
> kernel bug I found at New years, I've probably spent more time on these
> than on actual coding, and I suppose that is what I get for being an early
> adopter.  The as-released demo suffers from at least two SDL window
> handling glitches for which my application cannot provide workarounds, to
> wit, the "store settings" window size disconnect I've mentioned previously,
> and failure to handle deliver minimize/maximize events.  Now, with my code
> posted, everybody can see what I mean.  Also, on my first attempt to run
> this on a machine other than my laptop[4], SDL failed to create an OpenGL
> surface, though both xscreensaves-gl and abuse-sdl run fine on the machine.
>  I have not tracked down that issue yet.  Mesa, which I'm using for
> development, and which explains the fact that all the demos will run
> comfortably on low-end machines without 3D accelerators, proved to be a
> solid, accurate performer, and not totally useless from the performance
> point of view.  I ran into one subtle color shifting problem with unlit
> flat polygons, and some very obvious color artifacts that you will notice
> in the "waves" model (the Inca vase color patterns that emerge are
> gratuitious, and the use of linear color interpretation in screen space
> causes major color swimming problems when pologons are clipped).
> With OpenGL, attribute state leakage is a nontrivial problem, and I still
> do not have it completely under control, as you will see if you try out the
> keyboard controls in the shadow model demo, which managed to find yet more
> ways to change the color of the my polygon.  I suppose this is both a
> weakness and a strength of OpenGL, as it is very convenient to be able to
> have all those settable options lying around in default states until you
> realize you need to change them.  It's also a fine source of subtle bugs.
> Finally, these past three weeks having been my first experience with
> either, I'm most pleased with the combination of SDL and OpenGL as an
> immersive reality development platform, and feel comfortable in stating
> that I will stay with this combination for the long term.
> The code is here:
>   nl.linux.org/~phillips/world/world.zip
> Screenshots are here:
>    http://people.nl.linux.org/~phillips/world/
> Most of the download actually consists of a single data file for the
> wireframe demo world that I inherited from the original glut demo.  I
> suppose I should work up a demo to illustrate why ascii-encoding your
> wireframe data is a silly waste of time and space. :-)
> I provided the source as a zip file, imagining that this is friendlier for
> cross-platform purposes.  Please try to compile the code on your platform,
> and tell me what breaks.[5]
> Regards,
> Daniel
> [1] Stranger things have happened.
> [2] Somebody has been granted a trademark for the word "Pixels" and that is
> no joke.
> [3] Remembering, as usual, to credit your source.
> [4] Being able to develop this all on a laptop is a great credit to the
> toolchain
> [5] If you are using hardware acceleration, you'll probably notice that the
> frame rate is hard-coded pretty low.  That is because I have not yet taken
> the time to calibrate the physics for higher frame rates.   Sorry, I'll fix
> that soon.
> _______________________________________________
> SDL mailing list
> SDL at libsdl.org
> http://www.libsdl.org/mailman/listinfo/sdl

More information about the SDL mailing list