Files
BlitzNext/Runtime/blitz3d/model.cpp
T
Michael Fabian 'Xaymar' Dirks 3afa84df85 runtime/blitz3d: Fixup C++ification
2019-01-18 21:26:42 +01:00

140 lines
2.8 KiB
C++

#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<MeshQueue*>* que = &queues[type];
for (; que->size(); que->pop_back()) {
MeshQueue* q = que->back();
q->render();
delete q;
}
}