fteqw/engine/client/renderque.c
Spoike 6e3f69f504 d3d rendering is diabled (framestate, read later - merged will compile just sw+gl for now).
fte particle scripts are disabled (classic works).
I'll fix these in the new year.
Redid framestate stuff again. Slightly better now, but this is the bulk of the changes here.
Reworked the renderqueue to provide batches of items instead of individual items. This cleans up the particle rendering code significantly, and is a step towards multiple concurrent particle systems. fte's scripted particles are broken as I'm trying to find a way to rework them to batch types together, rather than having to restart each batch after each particle when you have two particles in a trail. I'll fix it some time.
Reworked some alias model code regarding skeletal models. Added some conceptual skeletal bone control builtins available to csqc. Currently it can query the bone names and save off animation states, but can't animate - its just not complete.
Added more info to glsl custom shaders.
Updated surface sorting on halflife maps to properly cope with alphaed entities, rather than just texture-based blends (q2-style).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3095 fc73d0e0-1445-4013-8a0c-d673dee63da5
2008-12-23 02:55:20 +00:00

138 lines
2.7 KiB
C

//this is to render transparent things in a distance oriented order
#include "quakedef.h"
#include "renderque.h"
#define NUMGRADUATIONS 0x400
static renderque_t *freerque;
static renderque_t *activerque;
static renderque_t *initialque;
static renderque_t *distlastarque[NUMGRADUATIONS];
static renderque_t *distrque[NUMGRADUATIONS];
int rqmaxgrad, rqmingrad;
int rquesize = 0x2000;
void RQ_AddDistReorder(void (*render) (int count, void **objects, void *objtype), void *object, void *objtype, float *pos)
{
int dist;
vec3_t delta;
renderque_t *rq;
if (!freerque)
{
render(1, &object, objtype);
return;
}
VectorSubtract(pos, r_refdef.vieworg, delta);
dist = Length(delta)/4;
if (dist > rqmaxgrad)
{
if (dist >= NUMGRADUATIONS)
dist = NUMGRADUATIONS-1;
rqmaxgrad = dist;
}
if (dist < rqmingrad)
{
if (dist < 0) //hmm... value wrapped? shouldn't happen
dist = 0;
rqmingrad = dist;
}
rq = freerque;
freerque = freerque->next;
rq->next = NULL;
if (distlastarque[dist])
distlastarque[dist]->next = rq;
distlastarque[dist] = rq;
rq->render = render;
rq->data1 = object;
rq->data2 = objtype;
if (!distrque[dist])
distrque[dist] = rq;
}
void RQ_RenderDistAndClear(void)
{
int i;
renderque_t *rq;
for (i = rqmaxgrad; i>=rqmingrad; i--)
// for (i = rqmingrad; i<=rqmaxgrad; i++)
{
for (rq = distrque[i]; rq; rq=rq->next)
{
rq->render(1, &rq->data1, rq->data2);
}
if (distlastarque[i])
{
distlastarque[i]->next = freerque;
freerque = distrque[i];
distrque[i] = NULL;
distlastarque[i] = NULL;
}
}
rqmaxgrad=0;
rqmingrad = NUMGRADUATIONS-1;
}
void RQ_RenderBatchClear(void)
{
#define SLOTS 512
void *slot[SLOTS];
void *typeptr = NULL;
int maxslot = SLOTS;
void (*lr) (int count, void **objects, void *objtype) = NULL;
int i;
renderque_t *rq;
for (i = rqmaxgrad; i>=rqmingrad; i--)
// for (i = rqmingrad; i<=rqmaxgrad; i++)
{
for (rq = distrque[i]; rq; rq=rq->next)
{
if (!maxslot || rq->render != lr || typeptr != rq->data2)
{
if (maxslot != SLOTS)
lr(SLOTS - maxslot, &slot[maxslot], typeptr);
maxslot = SLOTS;
}
slot[--maxslot] = rq->data1;
typeptr = rq->data2;
lr = rq->render;
}
if (distlastarque[i])
{
distlastarque[i]->next = freerque;
freerque = distrque[i];
distrque[i] = NULL;
distlastarque[i] = NULL;
}
}
if (maxslot != SLOTS)
lr(SLOTS - maxslot, &slot[maxslot], typeptr);
rqmaxgrad=0;
rqmingrad = NUMGRADUATIONS-1;
}
void RQ_Init(void)
{
int i;
if (initialque)
return;
initialque = (renderque_t *) Hunk_AllocName (rquesize * sizeof(renderque_t), "renderque");
freerque = &initialque[0];
activerque = NULL;
for (i=0 ;i<rquesize-1 ; i++)
initialque[i].next = &initialque[i+1];
initialque[rquesize-1].next = NULL;
}