]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_backend.c
use volatile on icolor and fcolor pointers in GL_ConvertColorsFloatToByte to avoid...
[xonotic/darkplaces.git] / gl_backend.c
index 5cdf1153f34fdf4062f0375acedfd0abecdd5ec0..d25ca67dbd1b3a20033e809853ec2473df90e1ef 100644 (file)
@@ -13,6 +13,9 @@ cvar_t r_render = {0, "r_render", "1"};
 cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1"}; // whether or not to use dithering
 cvar_t gl_lockarrays = {0, "gl_lockarrays", "1"};
 
+int gl_maxdrawrangeelementsvertices;
+int gl_maxdrawrangeelementsindices;
+
 #ifdef DEBUGGL
 int errornumber = 0;
 
@@ -221,14 +224,22 @@ static void gl_backend_shutdown(void)
 
 static void gl_backend_bufferchanges(int init)
 {
+       if (gl_mesh_drawmode.integer == 3 && qglDrawRangeElements != NULL)
+       {
+               if (gl_mesh_maxtriangles.integer * 3 > gl_maxdrawrangeelementsindices)
+                       Cvar_SetValueQuick(&gl_mesh_maxtriangles, (int) (gl_maxdrawrangeelementsindices / 3));
+               if (gl_mesh_maxtriangles.integer * 3 > gl_maxdrawrangeelementsvertices)
+                       Cvar_SetValueQuick(&gl_mesh_maxtriangles, (int) (gl_maxdrawrangeelementsvertices / 3));
+       }
+
        // 21760 is (65536 / 3) rounded off to a multiple of 128
-       if (gl_mesh_maxtriangles.integer < 256)
-               Cvar_SetValueQuick(&gl_mesh_maxtriangles, 256);
+       if (gl_mesh_maxtriangles.integer < 1024)
+               Cvar_SetValueQuick(&gl_mesh_maxtriangles, 1024);
        if (gl_mesh_maxtriangles.integer > 21760)
                Cvar_SetValueQuick(&gl_mesh_maxtriangles, 21760);
 
-       if (gl_mesh_transtriangles.integer < 256)
-               Cvar_SetValueQuick(&gl_mesh_transtriangles, 256);
+       if (gl_mesh_transtriangles.integer < 1024)
+               Cvar_SetValueQuick(&gl_mesh_transtriangles, 1024);
        if (gl_mesh_transtriangles.integer > 65536)
                Cvar_SetValueQuick(&gl_mesh_transtriangles, 65536);
 
@@ -581,25 +592,37 @@ void GL_UpdateFarclip(void)
 
 void GL_ConvertColorsFloatToByte(void)
 {
-       int i, k, *icolor;
-       float *fcolor;
+       int i, k, total;
+       // LordHavoc: to avoid problems with aliasing (treating memory as two
+       // different types - exactly what this is doing), these must be volatile
+       // (or a union)
+       volatile int *icolor;
+       volatile float *fcolor;
        qbyte *bcolor;
 
+       total = currentvertex * 4;
+
        // shift float to have 8bit fraction at base of number
-       for (i = 0, fcolor = &buf_fcolor->c[0];i < currentvertex;i++)
+       fcolor = &buf_fcolor->c[0];
+       for (i = 0;i < total;)
        {
-               *fcolor++ += 32768.0f;
-               *fcolor++ += 32768.0f;
-               *fcolor++ += 32768.0f;
-               *fcolor++ += 32768.0f;
+               fcolor[i    ] += 32768.0f;
+               fcolor[i + 1] += 32768.0f;
+               fcolor[i + 2] += 32768.0f;
+               fcolor[i + 3] += 32768.0f;
+               i += 4;
        }
+
        // then read as integer and kill float bits...
-       for (i = 0, icolor = (int *)&buf_fcolor->c[0], bcolor = &buf_bcolor->c[0];i < currentvertex;i++)
+       icolor = (int *)&buf_fcolor->c[0];
+       bcolor = &buf_bcolor->c[0];
+       for (i = 0;i < total;)
        {
-               k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k;
-               k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k;
-               k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k;
-               k = (*icolor++) & 0x7FFFFF;*bcolor++ = k > 255 ? 255 : k;
+               k = icolor[i    ] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i    ] = (qbyte) k;
+               k = icolor[i + 1] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 1] = (qbyte) k;
+               k = icolor[i + 2] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 2] = (qbyte) k;
+               k = icolor[i + 3] & 0x7FFFFF;if (k > 255) k = 255;bcolor[i + 3] = (qbyte) k;
+               i += 4;
        }
 }
 
@@ -1234,6 +1257,9 @@ void R_Mesh_Draw(const rmeshinfo_t *m)
        for (;j < backendunits;j++)
                memset(&texcoord[j][0].t[0], 0, m->numverts * sizeof(buf_texcoord_t));
        #endif
+
+       if (currenttriangle >= max_batch)
+               R_Mesh_Render();
 }
 
 void R_Mesh_Draw_NativeOnly(const rmeshinfo_t *m)
@@ -1406,6 +1432,9 @@ void R_Mesh_Draw_NativeOnly(const rmeshinfo_t *m)
                        fcolor[i].c[2] *= scaler;
                }
        }
+
+       if (currenttriangle >= max_batch)
+               R_Mesh_Render();
 }
 
 // allocates space in geometry buffers, and fills in pointers to the buffers in passsed struct