/* \brief free camera */ GLHCKAPI unsigned int glhckCameraFree(glhckCamera *object) { if (!glhckInitialized()) return 0; CALL(FREE_CALL_PRIO(object), "%p", object); assert(object); /* there is still references to this object alive */ if (--object->refCounter != 0) goto success; /* remove camera from global state */ if (GLHCKRD()->camera == object) GLHCKRD()->camera = NULL; /* free camera's object */ NULLDO(glhckObjectFree, object->object); /* remove camera from world */ _glhckWorldRemove(camera, object, glhckCamera*); /* free */ NULLDO(_glhckFree, object); success: RET(FREE_RET_PRIO(object), "%u", object?object->refCounter:0); return object?object->refCounter:0; }
/* \brief free texture */ GLHCKAPI unsigned int glhckTextureFree(glhckTexture *object) { unsigned int i; if (!glhckInitialized()) return 0; CALL(FREE_CALL_PRIO(object), "%p", object); assert(object); /* there is still references to this object alive */ if (--object->refCounter != 0) goto success; DEBUG(GLHCK_DBG_CRAP, "FREE(%p) %dx%dx%d", object, object->internalWidth, object->internalHeight, object->internalDepth); /* unbind from active slot */ for (i = 0; i != GLHCK_MAX_ACTIVE_TEXTURE; ++i) { if (GLHCKRD()->texture[i][object->target] == object) glhckTextureUnbind(object->target); } /* delete texture if there is one */ if (object->object) GLHCKRA()->textureDelete(1, &object->object); /* free */ IFDO(_glhckFree, object->file); /* remove from world */ _glhckWorldRemove(texture, object, glhckTexture*); /* free */ NULLDO(_glhckFree, object); success: RET(FREE_RET_PRIO(object), "%u", object?object->refCounter:0); return object?object->refCounter:0; }
/* \brief destroys the current glhck context */ GLHCKAPI void glhckContextTerminate(void) { if (!glhckInitialized()) return; TRACE(0); /* destroy queues */ _glhckFree(GLHCKRD()->objects.queue); _glhckFree(GLHCKRD()->textures.queue); /* destroy world */ glhckMassacreWorld(); /* terminate internal vertex/index types */ _glhckGeometryTerminate(); /* close display */ glhckDisplayClose(); /* terminate allocation tracking */ #ifndef NDEBUG puts("\nExit graph, this should be empty."); glhckMemoryGraph(); _glhckTrackTerminate(); #endif #if !GLHCK_DISABLE_TRACE /* terminate trace system */ _glhckTraceTerminate(); #endif /* finally remove the context */ free(_glhckContext); glhckContextSet(NULL); }
/* \brief free skin bone object */ GLHCKAPI unsigned int glhckSkinBoneFree(glhckSkinBone *object) { if (!glhckInitialized()) return 0; CALL(FREE_CALL_PRIO(object), "%p", object); assert(object); /* there is still references to this object alive */ if (--object->refCounter != 0) goto success; /* free the weights */ glhckSkinBoneInsertWeights(object, NULL, 0); /* remove from world */ _glhckWorldRemove(skinBone, object, glhckSkinBone*); /* free */ NULLDO(_glhckFree, object); success: RET(FREE_RET_PRIO(object), "%u", object?object->refCounter:0); return object?object->refCounter:0; }
/* \brief render scene */ GLHCKAPI void glhckRender(void) { unsigned int ti, oi, ts, os, tc, oc; char kt; glhckTexture *t; glhckObject *o; __GLHCKobjectQueue *objects; __GLHCKtextureQueue *textures; GLHCK_INITIALIZED(); TRACE(2); /* can't render */ if (!glhckInitialized() || !_glhckRenderInitialized()) return; objects = &GLHCKRD()->objects; textures = &GLHCKRD()->textures; /* store counts for enumeration, +1 for untexture objects */ tc = textures->count+1; oc = objects->count; /* nothing to draw */ if (!oc) return; /* draw in sorted texture order */ for (ti = 0, ts = 0; ti != tc; ++ti) { if (ti < tc-1) { if (!(t = textures->queue[ti])) continue; } else t = NULL; /* untextured object */ for (oi = 0, os = 0, kt = 0; oi != oc; ++oi) { if (!(o = objects->queue[oi])) continue; if (o->material) { /* don't draw if not same texture or opaque, * opaque objects are drawn last */ if (o->material->texture != t || (o->material->blenda != GLHCK_ZERO || o->material->blendb != GLHCK_ZERO)) { if (o->material->texture == t) kt = 1; /* don't remove texture from queue */ if (os != oi) objects->queue[oi] = NULL; objects->queue[os++] = o; continue; } } else if (t) { /* no material, but texture requested */ if (os != oi) objects->queue[oi] = NULL; objects->queue[os++] = o; continue; } /* render object */ glhckObjectRender(o); glhckObjectFree(o); /* referenced on draw call */ objects->queue[oi] = NULL; --objects->count; } /* check if we need texture again or not */ if (kt) { if (ts != ti) textures->queue[ti] = NULL; textures->queue[ts++] = t; } else { if (t) { glhckTextureFree(t); /* ref is increased on draw call! */ textures->queue[ti] = NULL; --textures->count; } } } /* store counts for enumeration, +1 for untextured objects */ tc = textures->count+1; oc = objects->count; /* FIXME: shift queue here */ if (oc) { } /* draw opaque objects next, * FIXME: this should not be done in texture order, * instead draw from farthest to nearest. (I hate opaque objects) */ for (ti = 0; ti != tc && oc; ++ti) { if (ti < tc-1) { if (!(t = textures->queue[ti])) continue; } else t = NULL; /* untextured object */ for (oi = 0, os = 0; oi != oc; ++oi) { if (!(o = objects->queue[oi])) continue; if (o->material) { /* don't draw if not same texture */ if (o->material->texture != t) { if (os != oi) objects->queue[oi] = NULL; objects->queue[os++] = o; continue; } } else if (t) { if (os != oi) objects->queue[oi] = NULL; objects->queue[os++] = o; continue; } /* render object */ glhckObjectRender(o); glhckObjectFree(o); /* referenced on draw call */ objects->queue[oi] = NULL; --objects->count; } /* this texture is done for */ if (t) { glhckTextureFree(t); /* ref is increased on draw call! */ textures->queue[ti] = NULL; --textures->count; } /* no texture, time to break */ if (!t) break; } /* FIXME: shift queue here if leftovers */ /* good we got no leftovers \o/ */ if (objects->count) { /* something was left un-drawn :o? */ for (oi = 0; oi != objects->count; ++oi) glhckObjectFree(objects->queue[oi]); memset(objects->queue, 0, objects->count * sizeof(glhckObject*)); objects->count = 0; } if (textures->count) { /* something was left un-drawn :o? */ DEBUG(GLHCK_DBG_CRAP, "COUNT UNLEFT %u", textures->count); for (ti = 0; ti != textures->count; ++ti) glhckTextureFree(textures->queue[ti]); memset(textures->queue, 0, textures->count * sizeof(glhckTexture*)); textures->count = 0; } }