#include "model.hpp" extern gxScene* gx_scene; class Model::MeshQueue { union { gxMesh* mesh; MeshQueue* next; }; int fv, vc, ft, tc; Brush brush; int q_type; // bool opaque; static MeshQueue* pool; public: MeshQueue() {} MeshQueue(gxMesh* m, int fv, int vc, int ft, int tc, const Brush& b) : mesh(m), fv(fv), vc(vc), ft(ft), tc(tc), brush(b) { int n = brush.getBlend(); q_type = (n == gxScene::BLEND_REPLACE) ? QUEUE_OPAQUE : QUEUE_TRANSPARENT; } int getQueueType() const { return q_type; } void render() { gx_scene->setRenderState(brush.getRenderState()); gx_scene->render(mesh, fv, vc, ft, tc); } void* operator new(size_t sz) { static const int GROW = 256; if (!pool) { pool = new MeshQueue[GROW]; for (int k = 0; k < GROW - 1; ++k) pool[k].next = &pool[k + 1]; pool[GROW - 1].next = 0; } MeshQueue* t = pool; pool = t->next; return t; } void operator delete(void* q) { MeshQueue* t = (MeshQueue*)q; t->next = pool; pool = t; } }; Model::MeshQueue* Model::MeshQueue::pool; Model::Model() : space(RENDER_SPACE_LOCAL), auto_fade(false), captured_alpha(1), w_brush(true) {} Model::Model(const Model& t) : Object(t), space(t.space), brush(t.brush), auto_fade(t.auto_fade), auto_fade_nr(t.auto_fade_nr), auto_fade_fr(t.auto_fade_fr), captured_alpha(t.captured_alpha), w_brush(true) {} void Model::capture() { Object::capture(); captured_alpha = brush.getAlpha(); } bool Model::beginRender(float t) { Object::beginRender(t); tweened_alpha = brush.getAlpha(); if (t != 1 && tweened_alpha != captured_alpha) { // //render tweening of alpha // tweened_alpha = (tweened_alpha - captured_alpha) * t + captured_alpha; } return tweened_alpha > 0; } bool Model::doAutoFade(const Vector& eye) { float alpha = tweened_alpha; if (auto_fade) { // //autofading of alpha // float d = eye.distance(getRenderTform().v); if (d >= auto_fade_fr) return false; if (d >= auto_fade_nr) { float t = 1 - (d - auto_fade_nr) / (auto_fade_fr - auto_fade_nr); alpha *= t; if (alpha <= 0) return false; } } if (w_brush) render_brush = brush; if (alpha != render_brush.getAlpha()) { render_brush.setAlpha(alpha); } else if (!w_brush) { return true; } setRenderBrush(render_brush); w_brush = false; return true; } void Model::enqueue(MeshQueue* q) { queues[q->getQueueType()].push_back(q); } void Model::enqueue(gxMesh* mesh, int fv, int vc, int ft, int tc) { enqueue(new MeshQueue(mesh, fv, vc, ft, tc, render_brush)); } void Model::enqueue(gxMesh* mesh, int fv, int vc, int ft, int tc, const Brush& brush) { enqueue(new MeshQueue(mesh, fv, vc, ft, tc, brush)); } void Model::renderQueue(int type) { std::vector* que = &queues[type]; for (; que->size(); que->pop_back()) { MeshQueue* q = que->back(); q->render(); delete q; } }