C Scene Graph

Started by
12 comments, last by GameDev.net 18 years, 8 months ago
Does anybody know of an example of a scene-graph implemented in pure C preferably using OpenGL? I'm trying to write my own, but unfortunately all I have to guide me are numerous books/papers/sources all focusing on C++. I've gotten to a point where things work and all, but now I'm having trouble advancing the development. I fear I may be missing something vital that will break my engine in the future. Thanks for your assistance.
http://blog.protonovus.com/
Advertisement
Quote:Original post by swordfish
Does anybody know of an example of a scene-graph implemented in pure C preferably using OpenGL? I'm trying to write my own, but unfortunately all I have to guide me are numerous books/papers/sources all focusing on C++. I've gotten to a point where things work and all, but now I'm having trouble advancing the development. I fear I may be missing something vital that will break my engine in the future. Thanks for your assistance.


Is there any particular reason you can't use C++?
The reason you can't find books on scene graphs in C is that the scene graph concept is object oriented almost by definition. C++ is therefore a much (and I mean much) better choice when implementing a scene graph. Anyway you could hack your way around it by having using structs in C:
struct node{    // variables    float        rot_matrix[16];    float        tra_matrix[16];    float        sca_matrix[16];    struct node *children;    // functions    void       (*draw)(); // assign the proper draw function to this variable};

or something along that line. Did I mention already that C++ would be much more suitable for implementing a scene graph? In C you cannot inherit from structs and since inheritance is at the core of most scene graphs, implementation will be a nightmare. You will have to reimplement the same thing over and over again for any other node types besides the base node. If the reason you want to use C and not C++ is your lack of C++ knowledge, I stronly recommend you to just learn C++ first before making any scene graph.

Tom
Creating a Scene Graph in C would be in interesting challenge. I can see it being implemented sort of like this (as a basic example)...

Here's some types:-
typedef enum{ NODE_TYPE_UNK = 0, NODE_TYPE_BASIC, NODE_TYPE_MODEL} node_type;typedef struct _vertex{  float x, y, z;} vertex;typedef struct node{    // variables    vertex      position;    vertex      rotation;    struct node *children;    int          childCount;    struct node *next;    struct node *parent;        node_type   type;    void        *node_data;} scene_node;typedef struct _modeldata{    int         vertCount;    vertex     *vertexData;} modeldata;


Here's some declarations:

void SG_render_node( scene_node *a_node );void SG_init_node( scene_node *a_node );void SG_render_model_node( scene_node *a_node );void SG_render_children( scene_node *a_node );scene_node * SG_create_node( node_type a_type );scene_node * SG_create_model_node( modeldata *a_data );


And here's some implementations:-
scene_node * SG_create_model_node( modeldata *a_data ){    scene_node *new_node = SG_create_node( NODE_TYPE_MODEL );    new_node->node_data = a_data;    return new_node;}scene_node * SG_create_node( node_type a_type ){    scene_node *new_node = malloc( sizeof(scene_node) );    SG_init_node( new_node );    new_node->type = a_type;    return new_node;}void SG_init_node( scene_node *a_node ){  a_node->parent = 0; a_node->children = 0;  a_node->childCount = 0;  a_node->type = NODE_TYPE_UNK;  a_node->node_data = 0;    a_node->position.x = a_node->position.y = a_node->position.z = 0;  a_node->rotation.x = a_node->rotation.y = a_node->rotation.z = 0;}void SG_render_node( scene_node *a_node ){     //glPushMatrix();     //glTranslate3f( a_node->position.x, a_node->position.y, a_node->position.z );     //glRotatef( a_node->rotation.x, a_node->rotation.y, a_node->rotation.z );     if ( a_node->type == NODE_TYPE_MODEL )     {        SG_render_model_node( a_node );     }      else     {         printf("Rendering basic node\n");     }         SG_render_children( a_node );          //glPopMatrix();}void SG_render_children( scene_node *a_node ){     scene_node *next = a_node->children;          printf(" - Rendering children\n");          while (next != 0)     {        SG_render_node( next );        next = next->next;     }}// Simple method to insert a child at the start of the parent listvoid SG_add_child( scene_node *a_parent, scene_node *a_child ){     a_child->next = a_parent->children;     a_parent->children = a_child;     a_child->parent = a_parent;     a_parent->childCount++;}void SG_render_model_node( scene_node *a_node ){   if ( a_node->type != NODE_TYPE_MODEL )  return;   // Get model data and render to screen   modeldata *data = (modeldata*) a_node->node_data;   printf("Rendering Model Node\n");}


With a quick example:-

int main(){    scene_node *root = SG_create_node( NODE_TYPE_BASIC );    scene_node *child = SG_create_model_node( 0 );        SG_add_child( root, child );        SG_render_node( root );	getch();	return 0;}


Note that I removed the OpenGL calls and didn't actually render a model [wink]. Of course, this is a very simple example and would need a lot more work to be really usable (deleting nodes, different types of nodes, etc), but it does show you that it can be done.
Yeah, implementing a scene-graph in C is a definite challenge and at times it can be a nightmare. The reason I chose C is mainly because I find it more intuitive than C++. I have knowledge of C++ and object-oriented programming, it's just that my C++ skills aren't exactly as sharp as are my C skills. When I look at C++ source like that in the WildMagic engine, I am just dumbfounded by how complicated it all looks - one could really get lost trying to perfect/optimize things.

Evolutional, that is somewhat how I have my scene-graph setup. Did you just come up with that or is that based on something that has been used/tested? I've got my scene graph working, it's just that things are starting to get tight as I add more functionality to it. I'm interested in seeing the results of a more complete C scene-graph than mine.
http://blog.protonovus.com/
Quote:Original post by swordfish
Yeah, implementing a scene-graph in C is a definite challenge and at times it can be a nightmare. The reason I chose C is mainly because I find it more intuitive than C++. I have knowledge of C++ and object-oriented programming, it's just that my C++ skills aren't exactly as sharp as are my C skills.


Why not use another simpler OO language then? all you'll end up doing is wasting your time implementing & maintaining OO constructs instead of using your time constructively on the problem itself. Also you'll most probably implement OO concepts less efficient than a language that supports OO constructs directly/natively.

Quote:Original post by swordfish
When I look at C++ source like that in the WildMagic engine, I am just dumbfounded by how complicated it all looks - one could really get lost trying to perfect/optimize things.


I doubt that if you really knew about OO and design patterns. Besides you don't have to use every feature of C++, do what you feel comfortable in it, take advantage of the OO support already there and do the others bits in C-ish style if you wish no point in wasting your time.

Quote:Original post by swordfish
Evolutional, that is somewhat how I have my scene-graph setup. Did you just come up with that or is that based on something that has been used/tested?


He probably just come up with it from the typical definition & implementation of scene graphs but in C.

Quote:Original post by swordfish
I've got my scene graph working, it's just that things are starting to get tight as I add more functionality to it. I'm interested in seeing the results of a more complete C scene-graph than mine.


I highly doubt you'll find a scene graph library written in C, I also believe the results of such thing will most likely be a maintance nightmare in C.

[Edited by - snk_kid on July 27, 2005 7:01:18 AM]
Quote:
When I look at C++ source like that in the WildMagic engine, I am just dumbfounded by how complicated it all looks - one could really get lost trying to perfect/optimize things.

I don't know WildMagic, but it might be that the complexity is just caused by the fact that it is a large project or perhaps it was poorly programmed. Have you tried looking for a more simple C++ scene graph example?

Anyway, the book we use for our CG course:

Interactive Computer Graphics: A Top-Down Approach Using OpenGL, 3rd Edition

by Edward Angel contains a chapter (chapter 9) about hierarchical modeling. It includes both a C and a C++ approach. You can find the C++ source code here (it's from the author's website so it should be legal), you'll have to search for the C code because his website is a bit buggy (i.e. broken links). Or you can just buy the book (although it's just a decent book, not particularly good).

Anyway, I would still advice you to go for the C++ approach. If you really don't want that, the post by evolutional shows a better way of doing it than my own. Apart from my post being a bit brief, the idea of the function pointer is rather ugly and is just me hacking my OO vision onto things into a non OO language :)

Tom
I don't see the larger "challenge" in creating a scene graph in C (I do prefer C to C++ by quite a margin [looksaround]). C++ is probably easier to use for the simpler, straightforward kinds of scene graphs to directly derive object types from scene graph nodes, but if you got arbitrary object types plugged in, you'll have to either allocate an object and assign it to an allocated scene node, or combine them and allocate once with some struct and memory tricks. Inheritance isn't possible in this case so C++ will pose exactly the same challenges.

I've coded an engine core totally based on C with extendable objects loaded from plugins and I'd say it's a lot more maintainable than static classes. Statically derived objects will need full rebuilds if any link in the chain is altered, I can extend objects locally and never rebuild anything I haven't touched [smile].

swordfish, I'd stop looking for a C implementation of a scene graph and instead figure out what object types you're gonna have and create a scene graph from that. A graph with container nodes pointing to object data should suffice, use a void* and maybe an object type identifier to call for proper actions when objects are processed.

Also, you should pull any strands of OpenGL from your scene graph unless you're making a rather small app. Scene graphs should know what's in the scene and how objects are related, the objects should know if they're visible and the renderer should know how to render things. If you start mixing those too much, you will get maintenance problems much larger than that of using non-OOP languages.

Atleast one guy promoting C for object management, hehe.
Quote:Original post by coelurus
I don't see the larger "challenge" in creating a scene graph in C (I do prefer C to C++ by quite a margin [looksaround]). C++ is probably easier to use for the simpler, straightforward kinds of scene graphs to directly derive object types from scene graph nodes, but if you got arbitrary object types plugged in, you'll have to either allocate an object and assign it to an allocated scene node, or combine them and allocate once with some struct and memory tricks. Inheritance isn't possible in this case so C++ will pose exactly the same challenges.

I don't think I understand the problem you describe, but your argument 'C++ is easier for the straightforward cases, but just as bad for some complex cases' doesn't sound like an argument against C++.

Quote:
Also, you should pull any strands of OpenGL from your scene graph unless you're making a rather small app. Scene graphs should know what's in the scene and how objects are related, the objects should know if they're visible and the renderer should know how to render things. If you start mixing those too much, you will get maintenance problems much larger than that of using non-OOP languages.

This, I fully agree with. It is true for both C and C++ implementations. It's the main reason I regret posting the example with the draw function pointer. I would never do it like that myself :)

Tom
Like I said, I've got the scene-graph up and running. It actually renders mesh-models and even has basic visibility culling support. I guess my problem is that I'm not really sure what type of objects I'm going to need. I got through implementing base-GroupNode and "derived" TransformNode and SwitchNode. Then I started on base-EntityNode and derived MeshNode and started confusing myself with thoughts of things like state management and such. >.< Thanks for your advice guys I really appreciate it.

P.S.
It's worthy to note that my goal is to implement a scene-graph that supports both spatial and semantic hierarchies (if that even makes sense).
http://blog.protonovus.com/
Quote:Original post by dimebolt
Quote:Original post by coelurus
I don't see the larger "challenge" in creating a scene graph in C (I do prefer C to C++ by quite a margin [looksaround]). C++ is probably easier to use for the simpler, straightforward kinds of scene graphs to directly derive object types from scene graph nodes, but if you got arbitrary object types plugged in, you'll have to either allocate an object and assign it to an allocated scene node, or combine them and allocate once with some struct and memory tricks. Inheritance isn't possible in this case so C++ will pose exactly the same challenges.

I don't think I understand the problem you describe, but your argument 'C++ is easier for the straightforward cases, but just as bad for some complex cases' doesn't sound like an argument against C++.


It wasn't an argument against C++, but an argument that the commonly known nifty features of C++ become obsolete => C is a totally viable choice of language for an extendable scene graph.
The choice of language is always about how efficiently you can develop a product including personal experience and code quality. In my case, C just worked (I started with C++ but faced some rather stupid problems which I got rid of when I switched to C) and C gives me all the tools I need to write managed code.

I don't see the point of merging spatial relationships into a scene graph since it often holds a very varied bunch of objects (large structures, dynamic objects, volumes such as lights, fog etc). Everything in the scene should be in the scene graph imho and making general spatial rules (that the scene graph should know of) for all object types in a big pool sounds rather daunting [smile]

This topic is closed to new replies.

Advertisement