]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_backend.c
added gl_delayfinish cvar (default off, used to always be on)
[xonotic/darkplaces.git] / gl_backend.c
index 9ce7459d2c5de3376f994ca4626ee63d49bec9b9..2d2ddc6a9500c1b6e9d7de0defccea1e6ba659a0 100644 (file)
@@ -5,6 +5,7 @@
 cvar_t gl_mesh_maxverts = {0, "gl_mesh_maxverts", "1024"};
 cvar_t gl_mesh_floatcolors = {0, "gl_mesh_floatcolors", "1"};
 cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1"};
+cvar_t gl_delayfinish = {CVAR_SAVE, "gl_delayfinish", "0"};
 
 cvar_t r_render = {0, "r_render", "1"};
 cvar_t gl_dither = {CVAR_SAVE, "gl_dither", "1"}; // whether or not to use dithering
@@ -51,7 +52,7 @@ void GL_PrintError(int errornumber, char *filename, int linenumber)
                break;
 #endif
 #ifdef GL_TABLE_TOO_LARGE
-    case GL_TABLE_TOO_LARGE:
+       case GL_TABLE_TOO_LARGE:
                Con_Printf("GL_TABLE_TOO_LARGE at %s:%i\n", filename, linenumber);
                break;
 #endif
@@ -202,6 +203,7 @@ void gl_backend_init(void)
        Cvar_RegisterVariable(&r_render);
        Cvar_RegisterVariable(&gl_dither);
        Cvar_RegisterVariable(&gl_lockarrays);
+       Cvar_RegisterVariable(&gl_delayfinish);
 #ifdef NORENDER
        Cvar_SetValue("r_render", 0);
 #endif
@@ -249,7 +251,7 @@ void GL_SetupView_Mode_Perspective (double fovx, double fovy, double zNear, doub
 
        // set up viewpoint
        qglMatrixMode(GL_PROJECTION);CHECKGLERROR
-       qglLoadIdentity ();CHECKGLERROR
+       qglLoadIdentity();CHECKGLERROR
        // pyramid slopes
        xmax = zNear * tan(fovx * M_PI / 360.0);
        ymax = zNear * tan(fovy * M_PI / 360.0);
@@ -261,14 +263,14 @@ void GL_SetupView_Mode_Perspective (double fovx, double fovy, double zNear, doub
 
 void GL_SetupView_Mode_PerspectiveInfiniteFarClip (double fovx, double fovy, double zNear)
 {
-       double nudge, m[16];
+       float nudge, m[16];
 
        if (!r_render.integer)
                return;
 
        // set up viewpoint
        qglMatrixMode(GL_PROJECTION);CHECKGLERROR
-       qglLoadIdentity ();CHECKGLERROR
+       qglLoadIdentity();CHECKGLERROR
        // set view pyramid
        nudge = 1.0 - 1.0 / (1<<23);
        m[ 0] = 1.0 / tan(fovx * M_PI / 360.0);
@@ -287,7 +289,7 @@ void GL_SetupView_Mode_PerspectiveInfiniteFarClip (double fovx, double fovy, dou
        m[13] = 0;
        m[14] = -2 * zNear * nudge;
        m[15] = 0;
-       qglLoadMatrixd(m);
+       qglLoadMatrixf(m);
        qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
        GL_SetupView_Orientation_Identity();
        backend_projectmatrix.m[0][0] = m[0];
@@ -315,7 +317,7 @@ void GL_SetupView_Mode_Ortho (double x1, double y1, double x2, double y2, double
 
        // set up viewpoint
        qglMatrixMode(GL_PROJECTION);CHECKGLERROR
-       qglLoadIdentity ();CHECKGLERROR
+       qglLoadIdentity();CHECKGLERROR
        qglOrtho(x1, x2, y2, y1, zNear, zFar);
        qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
        GL_SetupView_Orientation_Identity();
@@ -323,8 +325,8 @@ void GL_SetupView_Mode_Ortho (double x1, double y1, double x2, double y2, double
 
 typedef struct gltextureunit_s
 {
-       unsigned int t1d, t2d, t3d, tcubemap;
-       unsigned int arrayenabled;
+       int t1d, t2d, t3d, tcubemap;
+       int arrayenabled;
        float rgbscale, alphascale;
        int combinergb, combinealpha;
        // FIXME: add more combine stuff
@@ -528,35 +530,6 @@ void GL_ConvertColorsFloatToByte(int numverts)
        }
 }
 
-void GL_DrawRangeElements(int firstvert, int endvert, int indexcount, const int *index)
-{
-       int arraylocked = false;
-       c_meshs++;
-       c_meshelements += indexcount;
-       if (indexcount == 0 || endvert == firstvert)
-       {
-               Con_Printf("GL_DrawRangeElements(%d, %d, %d, %08p);\n", firstvert, endvert, indexcount, index);
-               return;
-       }
-       if (gl_supportslockarrays && gl_lockarrays.integer)
-       {
-               qglLockArraysEXT(firstvert, endvert - firstvert);
-               CHECKGLERROR
-               arraylocked = true;
-       }
-       if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
-               qglDrawRangeElements(GL_TRIANGLES, firstvert, endvert, indexcount, GL_UNSIGNED_INT, (const GLuint *) index);
-       else
-               qglDrawElements(GL_TRIANGLES, indexcount, GL_UNSIGNED_INT, (const GLuint *) index);
-       CHECKGLERROR
-       if (arraylocked)
-       {
-               qglUnlockArraysEXT();
-               CHECKGLERROR
-               arraylocked = false;
-       }
-}
-
 // enlarges geometry buffers if they are too small
 void _R_Mesh_ResizeCheck(int numverts)
 {
@@ -571,15 +544,36 @@ void _R_Mesh_ResizeCheck(int numverts)
 // renders the mesh
 void R_Mesh_Draw(int numverts, int numtriangles, const int *elements)
 {
-       BACKENDACTIVECHECK
-
-       CHECKGLERROR
-
+       int numelements;
+       if (numtriangles == 0 || numverts == 0)
+       {
+               Con_Printf("R_Mesh_Draw(%d, %d, %08p);\n", numverts, numtriangles, elements);
+               return;
+       }
+       numelements = numtriangles * 3;
+       c_meshs++;
+       c_meshelements += numelements;
        if (gl_state.colorarray && !gl_mesh_floatcolors.integer)
                GL_ConvertColorsFloatToByte(numverts);
        if (!r_render.integer)
                return;
-       GL_DrawRangeElements(0, numverts, numtriangles * 3, elements);
+       if (gl_supportslockarrays && gl_lockarrays.integer)
+       {
+               qglLockArraysEXT(0, numverts);
+               CHECKGLERROR
+               if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+                       qglDrawRangeElements(GL_TRIANGLES, 0, numverts, numelements, GL_UNSIGNED_INT, (const GLuint *) elements);
+               else
+                       qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) elements);
+               CHECKGLERROR
+               qglUnlockArraysEXT();
+               CHECKGLERROR
+       }
+       else
+       {
+               qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (const GLuint *) elements);
+               CHECKGLERROR
+       }
 }
 
 // restores backend state, used when done with 3D rendering
@@ -850,7 +844,7 @@ void R_Mesh_State(const rmeshstate_t *m)
 qboolean SCR_ScreenShot(char *filename, int x, int y, int width, int height)
 {
        qboolean ret;
-       int i;
+       int i, j;
        qbyte *buffer;
 
        if (!r_render.integer)
@@ -862,8 +856,13 @@ qboolean SCR_ScreenShot(char *filename, int x, int y, int width, int height)
 
        // LordHavoc: compensate for v_overbrightbits when using hardware gamma
        if (v_hwgamma.integer)
+       {
                for (i = 0;i < width * height * 3;i++)
-                       buffer[i] <<= v_overbrightbits.integer;
+               {
+                       j = buffer[i] << v_overbrightbits.integer;
+                       buffer[i] = (qbyte) (bound(0, j, 255));
+               }
+       }
 
        ret = Image_WriteTGARGB_preflipped(filename, width, height, buffer);
 
@@ -882,7 +881,10 @@ void R_ClearScreen(void)
                qglClearDepth(1);CHECKGLERROR
                if (gl_stencil)
                {
-                       qglClearStencil(0);CHECKGLERROR
+                       // LordHavoc: we use a stencil centered around 128 instead of 0,
+                       // to avoid clamping interfering with strange shadow volume
+                       // drawing orders
+                       qglClearStencil(128);CHECKGLERROR
                }
                // clear the screen
                qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (gl_stencil ? GL_STENCIL_BUFFER_BIT : 0));CHECKGLERROR
@@ -908,9 +910,12 @@ text to the screen.
 */
 void SCR_UpdateScreen (void)
 {
-       VID_Finish ();
+       if (gl_delayfinish.integer)
+       {
+               VID_Finish ();
 
-       R_TimeReport("finish");
+               R_TimeReport("finish");
+       }
 
        if (r_textureunits.integer > gl_textureunits)
                Cvar_SetValueQuick(&r_textureunits, gl_textureunits);
@@ -940,8 +945,17 @@ void SCR_UpdateScreen (void)
        // draw 2D stuff
        R_DrawQueue();
 
-       // tell driver to commit it's partially full geometry queue to the rendering queue
-       // (this doesn't wait for the commands themselves to complete)
-       qglFlush();
+       if (gl_delayfinish.integer)
+       {
+               // tell driver to commit it's partially full geometry queue to the rendering queue
+               // (this doesn't wait for the commands themselves to complete)
+               qglFlush();
+       }
+       else
+       {
+               VID_Finish ();
+
+               R_TimeReport("finish");
+       }
 }