]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_backend.c
added R_ScrollTexCoord2f (copies while texture coordinates with an offset)
[xonotic/darkplaces.git] / gl_backend.c
index 3bf290f826cb5804a6b00277ca0e004e5b68ba33..1ab98969ce70260e7872419c838aef201af7c7d8 100644 (file)
@@ -560,7 +560,7 @@ void GL_SetupTextureState(void)
                        qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);CHECKGLERROR
                        qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);CHECKGLERROR
                        qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);CHECKGLERROR
-                       qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB);CHECKGLERROR
+                       qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE_ARB mode
                        qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR
                        qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);CHECKGLERROR
                        qglTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);CHECKGLERROR
@@ -852,16 +852,6 @@ void R_Mesh_GetSpace(int numverts)
                }
        }
 
-/*
-#ifdef MESH_BATCH
-       if (gl_mesh_batching.integer)
-       {
-               if (gl_batchvertexcount == 0)
-                       gl_batchvertexfirst = varray_offset;
-               gl_batchvertexcount += numverts;
-       }
-#endif
-*/
        varray_vertex3f = varray_buf_vertex3f + varray_offset * 3;
        varray_color4f = varray_buf_color4f + varray_offset * 4;
        for (i = 0;i < backendunits;i++)
@@ -952,6 +942,54 @@ void R_Mesh_Draw(int numverts, int numtriangles, const int *elements)
        }
 }
 
+// renders triangles using vertices from the most recent GetSpace call
+// (can be multiple Draw calls per GetSpace)
+void R_Mesh_Draw_NoBatching(int numverts, int numtriangles, const int *elements)
+{
+       int numelements = numtriangles * 3;
+       if (numtriangles == 0 || numverts == 0)
+       {
+               Con_Printf("R_Mesh_Draw_NoBatching(%d, %d, %08p);\n", numverts, numtriangles, elements);
+               return;
+       }
+       c_meshs++;
+       c_meshelements += numelements;
+       CHECKGLERROR
+       if (gl_state.pointervertexcount)
+       {
+               if (r_render.integer)
+               {
+                       GL_LockArrays(0, gl_state.pointervertexcount);
+                       if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+                       {
+                               qglDrawRangeElements(GL_TRIANGLES, 0, gl_state.pointervertexcount, numelements, GL_UNSIGNED_INT, elements);CHECKGLERROR
+                       }
+                       else
+                       {
+                               qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, elements);CHECKGLERROR
+                       }
+                       GL_LockArrays(0, 0);
+               }
+       }
+       else
+       {
+               GL_Backend_RenumberElements(varray_buf_elements3i, numelements, elements, varray_offset);
+               if (r_render.integer)
+               {
+                       GL_LockArrays(varray_offset, numverts);
+                       if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+                       {
+                               qglDrawRangeElements(GL_TRIANGLES, varray_offset, varray_offset + numverts, numelements, GL_UNSIGNED_INT, varray_buf_elements3i);CHECKGLERROR
+                       }
+                       else
+                       {
+                               qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, varray_buf_elements3i);CHECKGLERROR
+                       }
+                       GL_LockArrays(0, 0);
+               }
+       }
+}
+
 // restores backend state, used when done with 3D rendering
 void R_Mesh_Finish(void)
 {
@@ -1093,22 +1131,19 @@ void R_Mesh_MainState(const rmeshstate_t *m)
                qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), p ? p : varray_buf_vertex3f);CHECKGLERROR
        }
 
-       if (gl_state.colorarray)
+       p = gl_state.pointervertexcount ? m->pointer_color : NULL;
+       if (gl_state.pointer_color != p)
        {
-               p = gl_state.pointervertexcount ? m->pointer_color : NULL;
-               if (gl_state.pointer_color != p)
-               {
 #ifdef MESH_BATCH
-                       if (gl_batchelementcount)
-                               R_Mesh_EndBatch();
+               if (gl_batchelementcount)
+                       R_Mesh_EndBatch();
 #endif
-                       gl_state.pointer_color = p;
-                       if (p != varray_buf_color4f || gl_mesh_floatcolors.integer)
-                               qglColorPointer(4, GL_FLOAT, sizeof(float[4]), p ? p : varray_buf_color4f);
-                       else
-                               qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(GLubyte[4]), p ? p : varray_buf_color4b);
-                       CHECKGLERROR
-               }
+               gl_state.pointer_color = p;
+               if (p || gl_mesh_floatcolors.integer)
+                       qglColorPointer(4, GL_FLOAT, sizeof(float[4]), p ? p : varray_buf_color4f);
+               else
+                       qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(GLubyte[4]), p ? p : varray_buf_color4b);
+               CHECKGLERROR
        }
 }
 
@@ -1548,7 +1583,7 @@ void R_Mesh_CopyTexCoord2f(int tmu, const float *texcoord2f, int numverts)
        if (mesh_var)
        {
                float *out = varray_texcoord2f[tmu];
-               while (--numverts)
+               while (numverts--)
                {
                        *out++ = *texcoord2f++;
                        *out++ = *texcoord2f++;
@@ -1565,7 +1600,7 @@ void R_Mesh_CopyColor4f(const float *color4f, int numverts)
        if (mesh_var)
        {
                float *out = varray_color4f;
-               while (--numverts)
+               while (numverts--)
                {
                        *out++ = *color4f++;
                        *out++ = *color4f++;
@@ -1578,6 +1613,15 @@ void R_Mesh_CopyColor4f(const float *color4f, int numverts)
                memcpy(varray_color4f, color4f, numverts * sizeof(float[4]));
 }
 
+void R_ScrollTexCoord2f (float *out2f, const float *in2f, int numverts, float s, float t)
+{
+       while (numverts--)
+       {
+               *out2f++ = *in2f++ + s;
+               *out2f++ = *in2f++ + t;
+       }
+}
+
 //===========================================================================
 // vertex array caching subsystem
 //===========================================================================
@@ -1659,6 +1703,7 @@ static void R_Mesh_CacheArray_Shutdown(void)
 {
 }
 
+/*
 static void R_Mesh_CacheArray_ValidateState(int num)
 {
        rcachearraylink_t *l, *lhead;
@@ -1670,6 +1715,7 @@ static void R_Mesh_CacheArray_ValidateState(int num)
                        return;
        Sys_Error("%i", num);
 }
+*/
 
 int R_Mesh_CacheArray(rcachearrayrequest_t *r)
 {
@@ -1677,7 +1723,7 @@ int R_Mesh_CacheArray(rcachearrayrequest_t *r)
        rcachearrayitem_t *d;
        int hashindex, offset, offsetend;
 
-       R_Mesh_CacheArray_ValidateState(3);
+       //R_Mesh_CacheArray_ValidateState(3);
        // calculate a hashindex to choose a cache chain
        r->data = NULL;
        hashindex = CRC_Block((void *)r, sizeof(*r)) % RCACHEARRAY_HASHSIZE;
@@ -1712,54 +1758,53 @@ int R_Mesh_CacheArray(rcachearrayrequest_t *r)
        offset = r_mesh_rcachedata_offset;
        r_mesh_rcachedata_offset += r->data_size;
        offsetend = r_mesh_rcachedata_offset;
-       R_Mesh_CacheArray_ValidateState(4);
+       //R_Mesh_CacheArray_ValidateState(4);
 
+       /*
        {
                int n;
                for (lhead = &r_mesh_rcachesequentialchain, l = lhead->next, n = 0;l != lhead;l = l->next, n++);
                Con_Printf("R_Mesh_CacheArray: new data range %i:%i, %i items are already linked\n", offset, offsetend, n);
        }
+       */
 
        // make room for the new data (remove old items)
        lhead = &r_mesh_rcachesequentialchain;
        l = r_mesh_rcachesequentialchain_current;
        if (l == lhead)
                l = l->next;
-       if (l != lhead)
+       while (l != lhead && l->data->offset < offsetend && l->data->offset + l->data->request.data_size > offset)
        {
-               while (l->data->offset < offsetend && l->data->offset + l->data->request.data_size > offset)
-               {
-       r_mesh_rcachesequentialchain_current = l;
-       R_Mesh_CacheArray_ValidateState(8);
-                       lnext = l->next;
-                       // if at the end of the chain, wrap around
-                       if (lnext == lhead)
-                               lnext = lnext->next;
-       r_mesh_rcachesequentialchain_current = lnext;
-       R_Mesh_CacheArray_ValidateState(10);
-
-                       // unlink from sequential chain
-                       l->next->prev = l->prev;
-                       l->prev->next = l->next;
-       R_Mesh_CacheArray_ValidateState(11);
-                       // link into free chain
-                       l->next = &r_mesh_rcachefreechain;
-                       l->prev = l->next->prev;
-                       l->next->prev = l->prev->next = l;
-       R_Mesh_CacheArray_ValidateState(12);
-
-                       l = &l->data->hashlink;
-                       // unlink from hash chain
-                       l->next->prev = l->prev;
-                       l->prev->next = l->next;
-
-                       l = lnext;
-       r_mesh_rcachesequentialchain_current = l;
-       R_Mesh_CacheArray_ValidateState(9);
-               }
+       //r_mesh_rcachesequentialchain_current = l;
+       //R_Mesh_CacheArray_ValidateState(8);
+               lnext = l->next;
+               // if at the end of the chain, wrap around
+               if (lnext == lhead)
+                       lnext = lnext->next;
+       //r_mesh_rcachesequentialchain_current = lnext;
+       //R_Mesh_CacheArray_ValidateState(10);
+
+               // unlink from sequential chain
+               l->next->prev = l->prev;
+               l->prev->next = l->next;
+       //R_Mesh_CacheArray_ValidateState(11);
+               // link into free chain
+               l->next = &r_mesh_rcachefreechain;
+               l->prev = l->next->prev;
+               l->next->prev = l->prev->next = l;
+       //R_Mesh_CacheArray_ValidateState(12);
+
+               l = &l->data->hashlink;
+               // unlink from hash chain
+               l->next->prev = l->prev;
+               l->prev->next = l->next;
+
+               l = lnext;
+       //r_mesh_rcachesequentialchain_current = l;
+       //R_Mesh_CacheArray_ValidateState(9);
        }
-       r_mesh_rcachesequentialchain_current = l;
-       R_Mesh_CacheArray_ValidateState(5);
+       //r_mesh_rcachesequentialchain_current = l;
+       //R_Mesh_CacheArray_ValidateState(5);
        // gobble an extra item if we have no free items available
        if (r_mesh_rcachefreechain.next == &r_mesh_rcachefreechain)
        {
@@ -1781,7 +1826,7 @@ int R_Mesh_CacheArray(rcachearrayrequest_t *r)
                l = lnext;
        }
        r_mesh_rcachesequentialchain_current = l;
-       R_Mesh_CacheArray_ValidateState(6);
+       //R_Mesh_CacheArray_ValidateState(6);
 
        // now take an item from the free chain
        l = r_mesh_rcachefreechain.next;
@@ -1797,13 +1842,13 @@ int R_Mesh_CacheArray(rcachearrayrequest_t *r)
        l->prev = l->next->prev;
        while (l->next->data && l->data && l->next->data->offset <= d->offset)
        {
-               Con_Printf(">\n");
+               //Con_Printf(">\n");
                l->next = l->next->next;
                l->prev = l->prev->next;
        }
        while (l->prev->data && l->data && l->prev->data->offset >= d->offset)
        {
-               Con_Printf("<\n");
+               //Con_Printf("<\n");
                l->prev = l->prev->prev;
                l->next = l->next->prev;
        }
@@ -1818,7 +1863,7 @@ int R_Mesh_CacheArray(rcachearrayrequest_t *r)
 
        //r_mesh_rcachesequentialchain_current = d->sequentiallink.next;
 
-       R_Mesh_CacheArray_ValidateState(7);
+       //R_Mesh_CacheArray_ValidateState(7);
        // and finally set the data pointer
        r->data = r_mesh_rcachedata + d->offset;
        // and tell the caller to fill the array