From: havoc Date: Fri, 2 Aug 2002 18:11:23 +0000 (+0000) Subject: added a mesh queue callback system (to allow mesh rendering things in different order... X-Git-Tag: RELEASE_0_2_0_RC1~392 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=c0f7a1b5470bc222b7a1d01ca95205c1825a5c6a added a mesh queue callback system (to allow mesh rendering things in different orders, etc) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2170 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/darkplaces.dsp b/darkplaces.dsp index 309fe914..1e6e6ffe 100644 --- a/darkplaces.dsp +++ b/darkplaces.dsp @@ -248,6 +248,10 @@ SOURCE=.\menu.c # End Source File # Begin Source File +SOURCE=.\meshqueue.c +# End Source File +# Begin Source File + SOURCE=.\model_alias.c # End Source File # Begin Source File @@ -544,6 +548,10 @@ SOURCE=.\menu.h # End Source File # Begin Source File +SOURCE=.\meshqueue.h +# End Source File +# Begin Source File + SOURCE=.\model_alias.h # End Source File # Begin Source File diff --git a/makefile b/makefile index 8feb568d..ebc44f03 100644 --- a/makefile +++ b/makefile @@ -22,7 +22,7 @@ SOUNDLIB= #if you want no CD audio CD=cd_null.o -OBJECTS= builddate.o $(CD) $(SND) chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o r_sky.o gl_rmain.o gl_rsurf.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_explosion.o sbar.o sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o protocol.o quakeio.o r_clip.o ui.o portals.o sys_shared.o cl_light.o gl_backend.o cl_particles.o cl_screen.o cgamevm.o cgame.o filematch.o collision.o cl_collision.o matrixlib.o cl_video.o dpvsimpledecode.o wavefile.o +OBJECTS= builddate.o $(CD) $(SND) chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o r_sky.o gl_rmain.o gl_rsurf.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_bsd.o net_udp.o net_dgrm.o net_loop.o net_main.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_explosion.o sbar.o sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o sys_linux.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o protocol.o quakeio.o r_clip.o ui.o portals.o sys_shared.o cl_light.o gl_backend.o cl_particles.o cl_screen.o cgamevm.o cgame.o filematch.o collision.o cl_collision.o matrixlib.o cl_video.o dpvsimpledecode.o wavefile.o meshqueue.o #K6/athlon optimizations CPUOPTIMIZATIONS=-march=k6 diff --git a/makefile.mingw b/makefile.mingw index 937f24d3..d306b4f9 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -1,5 +1,5 @@ -OBJECTS= builddate.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o r_sky.o gl_rmain.o gl_rsurf.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_dgrm.o net_loop.o net_main.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o protocol.o quakeio.o r_clip.o ui.o portals.o sys_shared.o cl_light.o gl_backend.o cl_particles.o cl_screen.o cgamevm.o cgame.o filematch.o collision.o cl_collision.o matrixlib.o cl_video.o dpvsimpledecode.o wavefile.o +OBJECTS= builddate.o chase.o cl_demo.o cl_input.o cl_main.o cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o fractalnoise.o gl_draw.o r_sky.o gl_rmain.o gl_rsurf.o host.o host_cmd.o image.o keys.o mathlib.o menu.o model_alias.o model_brush.o model_shared.o model_sprite.o net_dgrm.o net_loop.o net_main.o pr_cmds.o pr_edict.o pr_exec.o r_light.o r_explosion.o sbar.o snd_dma.o snd_mem.o snd_mix.o sv_main.o sv_move.o sv_phys.o sv_user.o sv_light.o transform.o view.o wad.o world.o zone.o vid_shared.o palette.o r_crosshairs.o gl_textures.o gl_models.o r_sprites.o r_modules.o r_explosion.o r_lerpanim.o protocol.o quakeio.o r_clip.o ui.o portals.o sys_shared.o cl_light.o gl_backend.o cl_particles.o cl_screen.o cgamevm.o cgame.o filematch.o collision.o cl_collision.o matrixlib.o cl_video.o dpvsimpledecode.o wavefile.o meshqueue.o #K6/athlon optimizations #CPUOPTIMIZATIONS=-march=k6 diff --git a/meshqueue.c b/meshqueue.c new file mode 100644 index 00000000..e75bddd1 --- /dev/null +++ b/meshqueue.c @@ -0,0 +1,175 @@ + +#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"}; + +typedef struct meshqueue_s +{ + struct meshqueue_s *next; + void (*callback)(void *data1, int data2); + void *data1; + int data2; + float dist; +} +meshqueue_t; + +float mqt_viewplanedist; +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"); + mq_total = 0; + mqt_total = 1000; + mq_array = NULL; + mqt_array = NULL; +} + +static void R_MeshQueue_Render(void) +{ + meshqueue_t *mq; + for (mq = mq_listhead;mq;mq = mq->next) + mq->callback(mq->data1, mq->data2); + mq_count = 0; + mq_listhead = NULL; +} + +static void R_MeshQueue_EnlargeTransparentArray(int newtotal) +{ + meshqueue_t *newarray; + newarray = Mem_Alloc(meshqueuemempool, newtotal * sizeof(meshqueue_t)); + if (mqt_array) + { + memcpy(newarray, mqt_array, mqt_total * sizeof(meshqueue_t)); + Mem_Free(mqt_array); + } + mqt_array = newarray; + mqt_total = newtotal; +} + +void R_MeshQueue_Add(void (*callback)(void *data1, int data2), void *data1, int data2) +{ + meshqueue_t *mq, **mqnext; + if (r_meshqueue_immediaterender.integer) + { + callback(data1, data2); + return; + } + if (mq_count >= mq_total) + R_MeshQueue_Render(); + mq = &mq_array[mq_count++]; + mq->callback = callback; + mq->data1 = data1; + mq->data2 = data2; + + // bubble-insert sort into meshqueue + mqnext = &mq_listhead; + if (r_meshqueue_sort.integer) + { + for(;;) + { + if (*mqnext) + { + if (mq->callback == (*mqnext)->callback) + { + if (mq->data1 == (*mqnext)->data1) + { + if (mq->data2 <= (*mqnext)->data2) + break; + } + else if (mq->data1 < (*mqnext)->data1) + break; + } + else if (mq->callback < (*mqnext)->callback) + break; + } + else + break; + mqnext = &(*mqnext)->next; + } + } + mq->next = *mqnext; + *mqnext = mq; +} + +void R_MeshQueue_AddTransparent(vec3_t center, void (*callback)(void *data1, int data2), void *data1, int data2) +{ + 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->dist = DotProduct(center, vpn) - mqt_viewplanedist; + mq->next = NULL; +} + +static void R_MeshQueue_RenderTransparent(void) +{ + int i; + int hashdist; + meshqueue_t *mqt; + meshqueue_t *hash[4096]; + memset(hash, 0, 4096 * sizeof(meshqueue_t *)); + for (i = 0, mqt = mqt_array;i < mqt_count;i++, mqt++) + { + // generate index + hashdist = (int) (mqt->dist); + hashdist = bound(0, hashdist, 4095); + // reversed to simplify render loop + hashdist = 4095 - hashdist; + // link into hash chain + mqt->next = hash[hashdist]; + hash[hashdist] = mqt; + } + for (i = 0;i < 4096;i++) + if (hash[i]) + for (mqt = hash[i];mqt;mqt = mqt->next) + R_MeshQueue_Add(mqt->callback, mqt->data1, mqt->data2); + mqt_count = 0; +} + +void R_MeshQueue_BeginScene(void) +{ + if (r_meshqueue_entries.integer < 1) + Cvar_SetValueQuick(&r_meshqueue_entries, 1); + if (r_meshqueue_entries.integer > 65536) + Cvar_SetValueQuick(&r_meshqueue_entries, 65536); + + if (mq_total != r_meshqueue_entries.integer || mq_array == NULL) + { + mq_total = r_meshqueue_entries.integer; + if (mq_array) + Mem_Free(mq_array); + mq_array = Mem_Alloc(meshqueuemempool, mq_total * sizeof(meshqueue_t)); + } + + if (mqt_array == NULL) + mqt_array = Mem_Alloc(meshqueuemempool, mqt_total * sizeof(meshqueue_t)); + + mq_count = 0; + mqt_count = 0; + mq_listhead = NULL; + mqt_viewplanedist = DotProduct(r_origin, vpn); +} + +void R_MeshQueue_EndScene(void) +{ + if (mqt_count) + R_MeshQueue_RenderTransparent(); + if (mq_count) + R_MeshQueue_Render(); +} + diff --git a/meshqueue.h b/meshqueue.h new file mode 100644 index 00000000..60b7aa46 --- /dev/null +++ b/meshqueue.h @@ -0,0 +1,11 @@ + +#ifndef MESHQUEUE_H +#define MESHQUEUE_H + +void R_MeshQueue_Init(void); +void R_MeshQueue_Add(void (*callback)(void *data1, int data2), void *data1, int data2); +void R_MeshQueue_AddTransparent(vec3_t center, void (*callback)(void *data1, int data2), void *data1, int data2); +void R_MeshQueue_BeginScene(void); +void R_MeshQueue_EndScene(void); + +#endif