]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - meshqueue.c
use sdl-config --static-libs on Mac
[xonotic/darkplaces.git] / meshqueue.c
index e75bddd112ac0fbcb57ae90dd470e875901fee6b..f313154442e6922c8b25f19ffe25810bb1dc6ff2 100644 (file)
@@ -9,8 +9,8 @@ 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;
+       void (*callback)(const void *data1, int data2);
+       const void *data1;
        int data2;
        float dist;
 }
@@ -21,24 +21,23 @@ 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;
+       mqt_total = 0;
        mq_array = NULL;
        mqt_array = NULL;
 }
 
-static void R_MeshQueue_Render(void)
+void R_MeshQueue_Render(void)
 {
        meshqueue_t *mq;
+       if (!mq_count)
+               return;
        for (mq = mq_listhead;mq;mq = mq->next)
                mq->callback(mq->data1, mq->data2);
        mq_count = 0;
@@ -48,7 +47,7 @@ static void R_MeshQueue_Render(void)
 static void R_MeshQueue_EnlargeTransparentArray(int newtotal)
 {
        meshqueue_t *newarray;
-       newarray = Mem_Alloc(meshqueuemempool, newtotal * sizeof(meshqueue_t));
+       newarray = Mem_Alloc(cl_mempool, newtotal * sizeof(meshqueue_t));
        if (mqt_array)
        {
                memcpy(newarray, mqt_array, mqt_total * sizeof(meshqueue_t));
@@ -58,7 +57,7 @@ static void R_MeshQueue_EnlargeTransparentArray(int newtotal)
        mqt_total = newtotal;
 }
 
-void R_MeshQueue_Add(void (*callback)(void *data1, int data2), void *data1, int data2)
+void R_MeshQueue_Add(void (*callback)(const void *data1, int data2), const void *data1, int data2)
 {
        meshqueue_t *mq, **mqnext;
        if (r_meshqueue_immediaterender.integer)
@@ -73,37 +72,35 @@ void R_MeshQueue_Add(void (*callback)(void *data1, int data2), void *data1, int
        mq->data1 = data1;
        mq->data2 = data2;
 
-       // bubble-insert sort into meshqueue
-       mqnext = &mq_listhead;
        if (r_meshqueue_sort.integer)
        {
-               for(;;)
+               // bubble-insert sort into meshqueue
+               for(mqnext = &mq_listhead;*mqnext;mqnext = &(*mqnext)->next)
                {
-                       if (*mqnext)
+                       if (mq->callback == (*mqnext)->callback)
                        {
-                               if (mq->callback == (*mqnext)->callback)
+                               if (mq->data1 == (*mqnext)->data1)
                                {
-                                       if (mq->data1 == (*mqnext)->data1)
-                                       {
-                                               if (mq->data2 <= (*mqnext)->data2)
-                                                       break;
-                                       }
-                                       else if (mq->data1 < (*mqnext)->data1)
+                                       if (mq->data2 <= (*mqnext)->data2)
                                                break;
                                }
-                               else if (mq->callback < (*mqnext)->callback)
+                               else if (mq->data1 < (*mqnext)->data1)
                                        break;
                        }
-                       else
+                       else if (mq->callback < (*mqnext)->callback)
                                break;
-                       mqnext = &(*mqnext)->next;
                }
        }
+       else
+       {
+               // maintain the order
+               for(mqnext = &mq_listhead;*mqnext;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)
+void R_MeshQueue_AddTransparent(const vec3_t center, void (*callback)(const void *data1, int data2), const void *data1, int data2)
 {
        meshqueue_t *mq;
        if (mqt_count >= mqt_total)
@@ -112,32 +109,37 @@ void R_MeshQueue_AddTransparent(vec3_t center, void (*callback)(void *data1, int
        mq->callback = callback;
        mq->data1 = data1;
        mq->data2 = data2;
-       mq->dist = DotProduct(center, vpn) - mqt_viewplanedist;
+       mq->dist = DotProduct(center, r_viewforward) - mqt_viewplanedist;
        mq->next = NULL;
 }
 
-static void R_MeshQueue_RenderTransparent(void)
+void R_MeshQueue_RenderTransparent(void)
 {
        int i;
        int hashdist;
        meshqueue_t *mqt;
-       meshqueue_t *hash[4096];
-       memset(hash, 0, 4096 * sizeof(meshqueue_t *));
+       meshqueue_t *hash[4096], **hashpointer[4096];
+       if (mq_count)
+               R_MeshQueue_Render();
+       if (!mqt_count)
+               return;
+       memset(hash, 0, sizeof(hash));
+       for (i = 0;i < 4096;i++)
+               hashpointer[i] = &hash[i];
        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;
+               // link to tail of hash chain (to preserve render order)
+               mqt->next = NULL;
+               *hashpointer[hashdist] = mqt;
+               hashpointer[hashdist] = &mqt->next;
        }
-       for (i = 0;i < 4096;i++)
+       for (i = 4095;i >= 0;i--)
                if (hash[i])
                        for (mqt = hash[i];mqt;mqt = mqt->next)
-                               R_MeshQueue_Add(mqt->callback, mqt->data1, mqt->data2);
+                               mqt->callback(mqt->data1, mqt->data2);
        mqt_count = 0;
 }
 
@@ -153,23 +155,29 @@ 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 = 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 = Mem_Alloc(cl_mempool, mqt_total * sizeof(meshqueue_t));
 
        mq_count = 0;
        mqt_count = 0;
        mq_listhead = NULL;
-       mqt_viewplanedist = DotProduct(r_origin, vpn);
+       mqt_viewplanedist = DotProduct(r_vieworigin, r_viewforward);
 }
 
 void R_MeshQueue_EndScene(void)
 {
-       if (mqt_count)
-               R_MeshQueue_RenderTransparent();
        if (mq_count)
+       {
+               Con_Printf("R_MeshQueue_EndScene: main mesh queue still has %i items left, flushing\n", mq_count);
                R_MeshQueue_Render();
+       }
+       if (mqt_count)
+       {
+               Con_Printf("R_MeshQueue_EndScene: transparent mesh queue still has %i items left, flushing\n", mqt_count);
+               R_MeshQueue_RenderTransparent();
+       }
 }