X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=meshqueue.c;h=6228d6d9c9cd419b696c139e26675133b746fb01;hb=604111986824e5f07f8cdb2b473ef2ae5681e24e;hp=24744f310895746d0276110450086ab4c8c776f3;hpb=805f263eee6c6b3504849972f1581d33cde86a04;p=xonotic%2Fdarkplaces.git diff --git a/meshqueue.c b/meshqueue.c index 24744f31..6228d6d9 100644 --- a/meshqueue.c +++ b/meshqueue.c @@ -2,34 +2,33 @@ #include "quakedef.h" #include "meshqueue.h" -cvar_t r_meshqueue_entries = {CVAR_SAVE, "r_meshqueue_entries", "16"}; -cvar_t r_meshqueue_immediaterender = {0, "r_meshqueue_immediaterender", "0"}; -cvar_t r_meshqueue_sort = {0, "r_meshqueue_sort", "0"}; +cvar_t r_meshqueue_entries = {CVAR_SAVE, "r_meshqueue_entries", "16", "maximum number of meshes to batch together and sort before issuing render calls (unused)"}; +cvar_t r_meshqueue_immediaterender = {0, "r_meshqueue_immediaterender", "0", "immediately render non-transparent meshes rather than batching"}; +cvar_t r_meshqueue_sort = {0, "r_meshqueue_sort", "0", "whether to sort meshes in a batch before issuing calls"}; typedef struct meshqueue_s { struct meshqueue_s *next; - void (*callback)(const void *data1, int data2); - const void *data1; - int data2; + void (*callback)(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight); + const entity_render_t *ent; + int surfacenumber; + const rtlight_t *rtlight; float dist; } meshqueue_t; float mqt_viewplanedist; +float mqt_viewmaxdist; meshqueue_t *mq_array, *mqt_array, *mq_listhead; int mq_count, mqt_count; int mq_total, mqt_total; -mempool_t *meshqueuemempool; - void R_MeshQueue_Init(void) { Cvar_RegisterVariable(&r_meshqueue_entries); Cvar_RegisterVariable(&r_meshqueue_immediaterender); Cvar_RegisterVariable(&r_meshqueue_sort); - meshqueuemempool = Mem_AllocPool("R_MeshQueue", 0, NULL); mq_total = 0; mqt_total = 0; mq_array = NULL; @@ -42,7 +41,7 @@ void R_MeshQueue_Render(void) if (!mq_count) return; for (mq = mq_listhead;mq;mq = mq->next) - mq->callback(mq->data1, mq->data2); + mq->callback(mq->ent, mq->surfacenumber, mq->rtlight); mq_count = 0; mq_listhead = NULL; } @@ -50,7 +49,7 @@ void R_MeshQueue_Render(void) static void R_MeshQueue_EnlargeTransparentArray(int newtotal) { meshqueue_t *newarray; - newarray = Mem_Alloc(meshqueuemempool, newtotal * sizeof(meshqueue_t)); + newarray = (meshqueue_t *)Mem_Alloc(cl_mempool, newtotal * sizeof(meshqueue_t)); if (mqt_array) { memcpy(newarray, mqt_array, mqt_total * sizeof(meshqueue_t)); @@ -60,20 +59,21 @@ static void R_MeshQueue_EnlargeTransparentArray(int newtotal) mqt_total = newtotal; } -void R_MeshQueue_Add(void (*callback)(const void *data1, int data2), const void *data1, int data2) +void R_MeshQueue_Add(void (*callback)(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight) { meshqueue_t *mq, **mqnext; if (r_meshqueue_immediaterender.integer) { - callback(data1, data2); + callback(ent, surfacenumber, rtlight); return; } if (mq_count >= mq_total) R_MeshQueue_Render(); mq = &mq_array[mq_count++]; mq->callback = callback; - mq->data1 = data1; - mq->data2 = data2; + mq->ent = ent; + mq->surfacenumber = surfacenumber; + mq->rtlight = rtlight; if (r_meshqueue_sort.integer) { @@ -82,12 +82,17 @@ void R_MeshQueue_Add(void (*callback)(const void *data1, int data2), const void { if (mq->callback == (*mqnext)->callback) { - if (mq->data1 == (*mqnext)->data1) + if (mq->ent == (*mqnext)->ent) { - if (mq->data2 <= (*mqnext)->data2) + if (mq->surfacenumber == (*mqnext)->surfacenumber) + { + if (mq->rtlight <= (*mqnext)->rtlight) + break; + } + else if (mq->surfacenumber < (*mqnext)->surfacenumber) break; } - else if (mq->data1 < (*mqnext)->data1) + else if (mq->ent < (*mqnext)->ent) break; } else if (mq->callback < (*mqnext)->callback) @@ -103,23 +108,26 @@ void R_MeshQueue_Add(void (*callback)(const void *data1, int data2), const void *mqnext = mq; } -void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const void *data1, int data2), const void *data1, int data2) +void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight), const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight) { meshqueue_t *mq; if (mqt_count >= mqt_total) R_MeshQueue_EnlargeTransparentArray(mqt_total + 100); mq = &mqt_array[mqt_count++]; mq->callback = callback; - mq->data1 = data1; - mq->data2 = data2; + mq->ent = ent; + mq->surfacenumber = surfacenumber; + mq->rtlight = rtlight; mq->dist = DotProduct(center, r_viewforward) - mqt_viewplanedist; mq->next = NULL; + mqt_viewmaxdist = max(mqt_viewmaxdist, mq->dist); } void R_MeshQueue_RenderTransparent(void) { int i; int hashdist; + float distscale; meshqueue_t *mqt; meshqueue_t *hash[4096], **hashpointer[4096]; if (mq_count) @@ -129,10 +137,11 @@ void R_MeshQueue_RenderTransparent(void) memset(hash, 0, sizeof(hash)); for (i = 0;i < 4096;i++) hashpointer[i] = &hash[i]; + distscale = 4095.0f / max(mqt_viewmaxdist, 4095); for (i = 0, mqt = mqt_array;i < mqt_count;i++, mqt++) { // generate index - hashdist = (int) (mqt->dist); + hashdist = (int) (mqt->dist * distscale); hashdist = bound(0, hashdist, 4095); // link to tail of hash chain (to preserve render order) mqt->next = NULL; @@ -142,7 +151,7 @@ void R_MeshQueue_RenderTransparent(void) for (i = 4095;i >= 0;i--) if (hash[i]) for (mqt = hash[i];mqt;mqt = mqt->next) - mqt->callback(mqt->data1, mqt->data2); + mqt->callback(mqt->ent, mqt->surfacenumber, mqt->rtlight); mqt_count = 0; } @@ -158,16 +167,17 @@ void R_MeshQueue_BeginScene(void) mq_total = r_meshqueue_entries.integer; if (mq_array) Mem_Free(mq_array); - mq_array = Mem_Alloc(meshqueuemempool, mq_total * sizeof(meshqueue_t)); + mq_array = (meshqueue_t *)Mem_Alloc(cl_mempool, mq_total * sizeof(meshqueue_t)); } if (mqt_array == NULL) - mqt_array = Mem_Alloc(meshqueuemempool, mqt_total * sizeof(meshqueue_t)); + mqt_array = (meshqueue_t *)Mem_Alloc(cl_mempool, mqt_total * sizeof(meshqueue_t)); mq_count = 0; mqt_count = 0; mq_listhead = NULL; mqt_viewplanedist = DotProduct(r_vieworigin, r_viewforward); + mqt_viewmaxdist = 0; } void R_MeshQueue_EndScene(void)