typedef to an (if possible) anonymous struct. The first struct member must be the parent class and should be named super. Following are the classes fields and possibly newly defined virtual methods.
Virtual methods are defined as function pointers in the class struct.
Example:
typedef struct { LsgNode super; void (*foobar)(float x); int visible; } LsgSample;
This division is necessary to allow the initializer being reused in descendant classes. Also it allows the creation of abstract classes by omitting the memory allocating part of the constructor.
NULL if an error is encountered while initializing the instance.LsgSample* LsgSample_create(void) { LsgSample* self = (LsgSample*)malloc(sizeof(LsgSample)); LsgSample_init(self); return self; }
Example:
void LsgSample_init(LsgSample* self) { LsgNode_init(&self->super); ((LsgObject*)self)->destroy = (void (*)(LsgObject*))LsgSample_destroy; ((LsgNode*)self)->display = (void (*)(LsgNode*, LsgFrustum*))LsgSample_display; self->foobar = LsgSample_foobar; self->show = 1; }
LsgObject_free to free any allocated resources prior to destroying an object instance. The general structure of the destructor method is:Example:
void LsgSample_destroy(LsgSample* self) { // free any allocated resources LsgNode_destroy(&self->super); }
The second parameter defines the current view frustum in object coordinates. You can use it to speed up rendering if part of the node are outside the visible area.
glPushAttrib and glPopAttrib to save and restore the OpenGL state rather then glGet or glIsEnabled. The latter may require the rendering pipeline to be flushed in order to determine the current state, which can have an impact on the display performance.void LsgSample_display(LsgSample* self, Frustum* frustum) { glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glBegin(GL_LINE_STRIP); glVertex2f(-1.0, -1.0); glVertex2f(-1.0, 1.0); glVertex2f( 1.0, 1.0); glVertex2f( 1.0, -1.0); glVertex2f(-1.0, -1.0); glEnd(); glPopAttrib(); // not strictly necessary; displays a neat bounding box if node.c has // been compiled with -DDEBUG_BBOX LsgNode_display(&self->super); }
void LsgSample_update(LsgSample* self, float now) { // hide the object after 60 seconds self->visible = now < 60.0; LsgNode_update(&self->super); }
Example (LsgGroup):
void LsgGroup_clean(LsgGroup* self) { LsgIterator* it; it = LsgIterator_create(self->children); while (LsgIterator_hasNext(it)) { LsgNode* child = (LsgNode*)LsgIterator_next(it); child->clean(child); } LsgObject_free((LsgObject*)it); LsgNode_clean(&self->super); }