[DEMO] Minimal world engine in SDL+OpenGL

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. :slight_smile:

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.

very interesting.
is this software usable under GLP?

regards.

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. :slight_smile:

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

Jesus Christ! Clip the excess bullshit next time!On 17-Jan-2003, Fabio Giovagnini wrote:

very interesting.
is this software usable under GLP?

regards.

Alle 05:59, venerd? 17 gennaio 2003, Daniel Phillips ha scritto:

Alot of bullshit


Patrick “Diablo-D3” McFarland || unknown at panax.com
"Computer games don’t affect kids; I mean if Pac-Man affected us as kids, we’d
all be running around in darkened rooms, munching magic pills and listening to
repetitive electronic music." – Kristian Wilson, Nintendo, Inc, 1989
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20030117/354332b6/attachment.pgp

Jesus Christ! Clip the excess bullshit next time!

But clipping the quoted text might cause him to accidentally read the
text, and if that happened then it’s possible he would’ve read where
Daniel said it was under the GPL, and thus never had the opportunity
to send the email in the first place.

Anyway, in a desperate effort to pretend this thread isn’t just noise
I’ll make a comment or two on the .zip…

  1. the zip contains a file called “world”, which causes all sorts of
    problems because it’s followed by a directory called “world”. My
    primitive OS can’t deal with a file and a directory attempting to
    posess the same name simultaneously, thus extracting the archive
    was in itself a minor challenge.

  2. once extracted, the “world/” directory didn’t compile, since the
    pthread library wasn’t included. Strangely enough, the Makefile
    in the parent directory did include -lpthread.

    -> You should be using sdl-config --cflags and sdl-config --libs
    to get the neccessary flags, if you can’t be bothered with the
    autoconf thing.

  3. with that fixed, the “world/” directory compiled okay. Compiling
    the “world” binary in the parent directory (after renaming world/
    to s-world/) went okay, running it produced a segfault.

  4. added -g flag and found the crash in set_videosize():

    if (!(video = SDL_GetVideoInfo())) return -1;
    surface = SDL_SetVideoMode(xpix, ypix, video->vfmt->BitsPerPixel, flags);
    if (!(video = SDL_GetVideoInfo())) return -2;

-> xpix = surface->w;

The return -2 check seems a bit strange; shouldn’t it be testing
if surface isn’t NULL? So I added:

if (surface == NULL)  return -3;

After that test, and run it again and get:

mike at satan:/tmp/z$ ./world
./world: can’t set video mode… Couldn’t find matching GLX visual

At this point I decided there’s something wrong with my setup anyway,
and gave up. :slight_smile:

If anyone’s read this far, I’d appreciate any ideas of things to try
to get accelerated OpenGL working properly. Currently, it sometimes
works. GLTron for example, seems to be accelerated. GL screensavers
from xscreensavers fail fullscreen (with the message “Couldn’t create
GL context for visual 0x21”), but work when windowed.

GeForce4 MX, evil nVidia binary drivers v4191, stock 2.4.21-pre2 with
rml’s preemptible kernel patches (same behaviour on earlier versions
of the drivers and different kernel, too).On Fri, Jan 17, 2003 at 04:29:31AM -0500, Patrick McFarland wrote:

On 17-Jan-2003, Fabio Giovagnini wrote:

very interesting.
is this software usable under GLP?

regards.

Alle 05:59, venerd? 17 gennaio 2003, Daniel Phillips ha scritto:

Alot of bullshit
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20030117/5586453b/attachment.pgp

You mean GPL? Yes, it’s GPL.

Regards,

DanielOn Friday 17 January 2003 10:15, Fabio Giovagnini wrote:

very interesting.
is this software usable under GLP?

  1. the zip contains a file called “world”, which causes all sorts of
    problems because it’s followed by a directory called “world”. My
    primitive OS can’t deal with a file and a directory attempting to
    posess the same name simultaneously, thus extracting the archive
    was in itself a minor challenge.

It’s not your OS, it’s me messing up by zipping into an already-existing zip
file that contained an uncleaned copy of the tree, complete with bogus
binaries. A new zipfile, including updated makefile and SetVideo error
check, is at:

http://people.nl.linux.org/~phillips/world/world.zip

It’s less than 1/3 the size, much more reasonable.

  1. once extracted, the “world/” directory didn’t compile, since the
    pthread library wasn’t included. Strangely enough, the Makefile
    in the parent directory did include -lpthread.

My code doesn’t use pthread, and the pthread library is not required in order
to compile on my (Debian) system. I’d like to know where this dependency
comes from before I change the makefile. Can you double-check it’s actually
needed, please? Perhaps it’s needed only for some configurations of libsdl.

-> You should be using sdl-config --cflags and sdl-config --libs
to get the neccessary flags, if you can’t be bothered with the
autoconf thing.

A configure script plus all the usual tool-generated boilerplate
would be several times longer than my entire demo, and I do not want to be
part of that bloat problem. Perhaps for a full project, but for a demo.
Personally, I tend to appreciate a demo that comes with a minimal makefile,
or none at all, a lot more than one full of files that aren’t actually
needed, which the author didn’t write, and do not help me improve my
understanding of the interesting parts.

I added the sdl-config --cflags, even though I don’t see that its doing
anything useful. (Maybe it will some time in the future.) I’m always deeply
suspicious about flags that begin with _, and -D_REENTRANT is no exception.
Who/what acts on this flag? Since my demo is single-threaded, I doubt I need
it. Is it needed for, say, Windows?

The return -2 check seems a bit strange; shouldn’t it be testing
if surface isn’t NULL?

Yes, thanks. I inherited that wrong code from a demo and corrected it some
time ago.

…run it again and get:

mike at satan:/tmp/z$ ./world
./world: can’t set video mode… Couldn’t find matching GLX visual

At this point I decided there’s something wrong with my setup anyway,
and gave up. :slight_smile:

Have you ever run an SDL+OpenGL demo? I also have a machine here that won’t
run the demo, but does run various SDL games and the non-SDL OpenGL
xscreensaver-gl demos. I’d like to get to the bottom of this weirdness.

If anyone’s read this far, I’d appreciate any ideas of things to try
to get accelerated OpenGL working properly.

I haven’t actually run it on an accelerated machine myself, just software
Mesa, which explains the low polygon counts. Please do keep trying things,
for example, try compiling the original version of the waves demo, which uses
SDL+OpenGL:

http://home.in.tum.de/~thomsen/Computer/Programs/WaveGL.html

Currently, it sometimes
works. GLTron for example, seems to be accelerated. GL screensavers
from xscreensavers fail fullscreen (with the message “Couldn’t create
GL context for visual 0x21”), but work when windowed.

My demo starts in a window. Could it have something to do with the requested
OpenGL attributes? i.e.,

SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 3);

But I don’t see anything odd there. Need more data…

GeForce4 MX, evil nVidia binary drivers v4191, stock 2.4.21-pre2 with
rml’s preemptible kernel patches (same behaviour on earlier versions
of the drivers and different kernel, too).

Good luck.

Daniel> On Fri, Jan 17, 2003 at 04:29:31AM -0500, Patrick McFarland wrote:

Some time before, I wrote:

  1. once extracted, the “world/” directory didn’t compile, since the
    pthread library wasn’t included. Strangely enough, the Makefile
    in the parent directory did include -lpthread.

My code doesn’t use pthread, and the pthread library is not required
in order to compile on my (Debian) system. I’d like to know where
this dependency comes from before I change the makefile. Can you
double-check it’s actually needed, please? Perhaps it’s needed only
for some configurations of libsdl.

Interesting; this is on a Debian system, too (sid).

Relevant package versions:
libsdl1.2-dev 1.2.4-1
libsdl1.2debian-oss 1.2.4-1
libsdl-image1.2 1.2.2-5
libsdl-mixer1.2 1.2.4-3
libsdl-net1.2 1.2.4-2
libsdl-ttf1.2 1.2.2-1.1

sdl-config --libs returns:
-L/usr/lib -lSDL -lpthread

and the binaries definitely require libpthread.

sdl-config --cflags returns:
-I/usr/include/SDL -D_REENTRANT

-> You should be using sdl-config --cflags and sdl-config --libs
to get the neccessary flags, if you can’t be bothered with the
autoconf thing.

[snip: configure script for a demo excessive. Yeah, I tend to agree. I
just downloaded the source for the “netspeed” applet, which included a
42kB .c file and a 300kB configure script. g]

I added the sdl-config --cflags, even though I don’t see that its
doing anything useful. (Maybe it will some time in the future.) I’m
always deeply suspicious about flags that begin with _, and
-D_REENTRANT is no exception. Who/what acts on this flag? Since my
demo is single-threaded, I doubt I need it. Is it needed for, say,
Windows?

Possibly; all I know is that on my system it seems to be required, as
it refuses to link without -lpthread:

/usr/lib/libSDL.so: undefined reference to pthread_create' /usr/lib/libSDL.so: undefined reference topthread_cancel’
/usr/lib/libSDL.so: undefined reference to `sem_destroy’
etc.

That’s with gcc-2.95, but I get similar messages with gcc-3.2, too.

Changing -lSDL to sdl-config --libs allows it to compile fine, albeit
with two warnings:
world.c: In function do_button': world.c:520: warning: implicit declaration of functionmemset’
worlds/wireframe.c: In function loader': worlds/wireframe.c:25: warning: implicit declaration of functionexit’

Anyway, once compiled it still refuses to run for the same reason as
before.

I haven’t actually run it on an accelerated machine myself, just
software Mesa, which explains the low polygon counts. Please do keep
trying things, for example, try compiling the original version of the
waves demo, which uses SDL+OpenGL:

http://home.in.tum.de/~thomsen/Computer/Programs/WaveGL.html

That one works fine (even in 1024x768 fullscreen), and runs fast enough
to confirm it’s accelerated.

My demo starts in a window. Could it have something to do with the
requested OpenGL attributes? i.e.,

[snip]

But I don’t see anything odd there. Need more data…

I don’t have a clue about OpenGL, but I had a look at the attributes
the WaveGL demo uses and compared it to what you used, and changed the:

SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);

to

SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);

and now it all works. shrug

Only problem I found was with resizing the window, which results in a
lot of redraws and takes a very long time. Perhaps if it processed
all the resize events and then actually resized only once at the end
it would be faster. I think the slowness may be caused by Sawfish as
jumping to another workspace (so it wasn’t displaying the window) and
back was a /lot/ faster than watching it keep trying to resize.

Aside from that – the demos look good. Nice work!
-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20030122/001852be/attachment.pgpOn Wed, Jan 22, 2003 at 02:58:31AM +0100, Daniel Phillips wrote:

Changing -lSDL to sdl-config --libs allows it to compile fine, albeit
with two warnings:
world.c: In function do_button': world.c:520: warning: implicit declaration of functionmemset’
worlds/wireframe.c: In function loader': worlds/wireframe.c:25: warning: implicit declaration of functionexit’

The “exit(1)” in wireframe.c is bogus and should be replaced by return -1, as
it is not the data loader’s responsibility to decide whether to abort an
application, only to report failure. I didn’t catch that because gcc 2.95.4
incorrectly fails to report the implicit definition. (Time to change default
compiler, almost…) The memsets are also bogus and should be deleted but
otherwise they’d need #include <string.h>.

I fixed those glitches, added the pthread dependency to the Makefile and
updated the zip at:

http://people.nl.linux.org/~phillips/world/world.zip

Anyway, once compiled it still refuses to run for the same reason as
before.

Yes, now the real problem…

…Could it have something to do with the
requested OpenGL attributes? i.e.,

[snip]

But I don’t see anything odd there. Need more data…

I don’t have a clue about OpenGL, but I had a look at the attributes
the WaveGL demo uses and compared it to what you used, and changed the:

SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);

to

SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);

and now it all works. shrug

Nice shooting. OK, your card doesn’t support a 32 bit depth buffer, or the
driver doesn’t. The (pathetic excuse for) specs on NVidia’s site say that
your gforce4 supports a 32 bit depth buffer, so we’ve got a software problem.
It’s unlikely such a gross driver problem would slip through, so naturally I
suspect SDL here, being the youngest of the components involved.

Unfortunately, a 16 bit depth buffer is simply inadequate for a walk-around
environment, as you have to clip away the scene annoyingly far from the
observer’s nose in order to preserve enough resolution to render accurately
over a reasonable distance. You’ll see artifacts in the shadow demo as a
result of this. The demo can be modified to use a bigger separation between
the shadow polygons and the shadowed surface, but this will break as soon as
you step back some distance from the object. Or the visibility algorithm
could be changed to, for example, bsp, a nontrivial amount of work but
perhaps worth doing. Setting the depth buffer to 32 bits is the only
reasonably convenient solution. With the massive amounts of memory on
graphics cards today, who is going to notice a doubling of the depth buffer
size? This one needs to be tracked down.

Only problem I found was with resizing the window, which results in a
lot of redraws and takes a very long time. Perhaps if it processed
all the resize events and then actually resized only once at the end
it would be faster.

Could you please define “very long time”?

It’s fast here. The demo is limited to 15 screen flips per second (I know,
it’s too low, it’s on my list of things to fix). It redraws exactly once if
you maximize the window and redraws at the expected rate if you drag the
window corner.

I think the slowness may be caused by Sawfish as
jumping to another workspace (so it wasn’t displaying the window) and
back was a /lot/ faster than watching it keep trying to resize.

It smells like a window manager bug all right. You can do a quick test under
KDE without shutting down Gnome by getting to a new virtual console with,
say, Alt-F2 and doing:

xinit /usr/bin/kde2 – :1

which will give you a kde session on the Alt-F8 virtual console.

You can also change the off(printf(“Resize %i to %i, %i\n”… in the
SDL_VIDEORESIZE event handler to “on”, and see how many resize events are
being delivered at which sizes, which may shed some light on the problem.

Aside from that – the demos look good. Nice work!

Thanks. Did you find the feature in the waves demo that lets you make
splashes with the mouse?

Regards,

DanielOn Wednesday 22 January 2003 10:49, Michael Alger wrote:

This is what I do for my nvidia card… I can do 32 bit stuff with it…

/etc/XF86ConfigOn Wed, 2003-01-22 at 12:20, Daniel Phillips wrote:

Nice shooting. OK, your card doesn’t support a 32 bit depth buffer, or the
driver doesn’t. The (pathetic excuse for) specs on NVidia’s site say that
your gforce4 supports a 32 bit depth buffer, so we’ve got a software problem.


Section "Screen"
Identifier "DefaultDisplay"
Device "nVidia GeForce3 Ti200"
Monitor "Display1"
DefaultDepth 24
DefaultFbBPP 32
SubSection "Display"
Depth 24
Modes “1600x1200” “1280x1024” “1152x864” "1024x768"
“800x600” "640x480"
EndSubSection
EndSection

Hmm, nm, I can only get up to 24 with your demo. But I just tested out
lesson17 from the OpenGL-intro package and changed everything to 32 bits
there and it worked without complaints. (at fullscreen and not)On Wed, 2003-01-22 at 13:28, Stacey Keast wrote:

On Wed, 2003-01-22 at 12:20, Daniel Phillips wrote:

Nice shooting. OK, your card doesn’t support a 32 bit depth buffer, or the
driver doesn’t. The (pathetic excuse for) specs on NVidia’s site say that
your gforce4 supports a 32 bit depth buffer, so we’ve got a software problem.

This is what I do for my nvidia card… I can do 32 bit stuff with it…

/etc/XF86Config

All of the the depths you mentioned are color depths, not frame buffer
depths. I don’t know what madness the various layers are using to determine
which z-buffer depths are available, but I can say it makes very little sense.

There, now that I have that off my chest, It seems that SDL+OpenGL is only
going to start up on a wide range of hardware if you don’t specify any
GL_SetAttributes at all. Just comment them all out and I guess it will
start, but you will likely have a sucky 16 bit zbuffer. Please try
uncommenting just the SDL_GL_DEPTH_SIZE line to get a 32 bit zbuffer and see
if it starts.

With Mesa software rendering on one of my machines here, SDL+OpenGL refuses
to create a surface with a 32 bit z-buffer. That makes no sense whatsoever -
somebody is dropping the ball, either XFree, Mesa, or SDL. Besides searching
for the guilty party in the driver chain, I suppose I also need to implement
a fallback strategy in my demo, where I keep trying wimpier configurations
until one of them returns a non-zero surface. Then in the .create method of
the one demo world that cares about the z-buffer depth (shadow), I can fail
out with a message and have that demo not run, or run with an empty world,
rather than run with artifacts. This strategy will hopefully draw some
attention to the configuration disconnects, rather than working around them
and pretending everything’s fine.

I’ll go take a look at the SDL part of the init path now, to see if anything
obvious jumps out at me.

Regards,

DanielOn Wednesday 22 January 2003 22:13, Stacey Keast wrote:

On Wed, 2003-01-22 at 13:28, Stacey Keast wrote:

On Wed, 2003-01-22 at 12:20, Daniel Phillips wrote:

Nice shooting. OK, your card doesn’t support a 32 bit depth buffer, or
the driver doesn’t. The (pathetic excuse for) specs on NVidia’s site
say that your gforce4 supports a 32 bit depth buffer, so we’ve got a
software problem.

This is what I do for my nvidia card… I can do 32 bit stuff with it…

/etc/XF86Config

Hmm, nm, I can only get up to 24 with your demo. But I just tested out
lesson17 from the OpenGL-intro package and changed everything to 32 bits
there and it worked without complaints. (at fullscreen and not)

Daniel Phillips wrote:> On Wednesday 22 January 2003 22:13, Stacey Keast wrote:

On Wed, 2003-01-22 at 13:28, Stacey Keast wrote:

On Wed, 2003-01-22 at 12:20, Daniel Phillips wrote:

Nice shooting. OK, your card doesn’t support a 32 bit depth buffer, or
the driver doesn’t. The (pathetic excuse for) specs on NVidia’s site
say that your gforce4 supports a 32 bit depth buffer, so we’ve got a
software problem.

This is what I do for my nvidia card… I can do 32 bit stuff with it…

/etc/XF86Config

Hmm, nm, I can only get up to 24 with your demo. But I just tested out
lesson17 from the OpenGL-intro package and changed everything to 32 bits
there and it worked without complaints. (at fullscreen and not)

All of the the depths you mentioned are color depths, not frame buffer
depths. I don’t know what madness the various layers are using to determine
which z-buffer depths are available, but I can say it makes very little sense.

There, now that I have that off my chest, It seems that SDL+OpenGL is only
going to start up on a wide range of hardware if you don’t specify any
GL_SetAttributes at all. Just comment them all out and I guess it will
start, but you will likely have a sucky 16 bit zbuffer. Please try
uncommenting just the SDL_GL_DEPTH_SIZE line to get a 32 bit zbuffer and see
if it starts.

You have to request a 24 bit color to get 32 bit depth, and optionally,
8 bit stencil.

.s - IIRC

Nice theory, but it doesn’t hold here. I set each of (SDL_GL_) RED, GREEN
and BLUE to 8 and BUFFER_SIZE to 24 and still fail to get a "matching visual"
on my test machine if DEPTH_SIZE is 32 instead of 16. Good thing too,
because such a coupling of unrelated attributes would be perverse. There is
no reason to stop searching for the real culprit. There is no question
there’s a culprit: as a software renderer, Mesa is capable of setting up
whichever depths it chooses.

Regards,

DanielOn Wednesday 22 January 2003 23:53, Santeri Hernej?rvi wrote:

Daniel Phillips wrote:

…It seems that SDL+OpenGL is
only going to start up on a wide range of hardware if you don’t specify
any GL_SetAttributes at all. Just comment them all out and I guess it
will start, but you will likely have a sucky 16 bit zbuffer. Please try
uncommenting just the SDL_GL_DEPTH_SIZE line to get a 32 bit zbuffer and
see if it starts.

You have to request a 24 bit color to get 32 bit depth, and optionally,
8 bit stencil.

Why not use sdl-config --libs? That is what it exists for.On Wed, Jan 22, 2003 at 08:20:50PM +0100, Daniel Phillips wrote:

I fixed those glitches, added the pthread dependency to the Makefile and
updated the zip at:

http://people.nl.linux.org/~phillips/world/world.zip


Joseph Carter <@Joseph_Carter> Not ready for prime-time

There are worse things than Perl…ASP comes to mind

-------------- next part --------------
A non-text attachment was scrubbed…
Name: not available
Type: application/pgp-signature
Size: 253 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20030123/50397812/attachment.pgp