]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_backend.c
bmodel shadow volumes
[xonotic/darkplaces.git] / gl_backend.c
index 9af28f192c9c66caa7614023f65b8adcf94b533f..2ec09f0bc95c0d97e1866405a9bba87fe4ce67c9 100644 (file)
@@ -63,18 +63,13 @@ void GL_PrintError(int errornumber, char *filename, int linenumber)
 
 #define BACKENDACTIVECHECK if (!backendactive) Sys_Error("GL backend function called when backend is not active\n");
 
-float r_mesh_farclip;
-
 int c_meshs, c_meshelements;
 
-int lightscalebit;
-float lightscale;
-float overbrightscale;
-
 void SCR_ScreenShot_f (void);
 
 // these are externally accessible
-float mesh_colorscale;
+int r_lightmapscalebit;
+float r_colorscale;
 float *varray_vertex;
 float *varray_color;
 float *varray_texcoord[MAX_TEXTUREUNITS];
@@ -199,77 +194,63 @@ void gl_backend_init(void)
        R_RegisterModule("GL_Backend", gl_backend_start, gl_backend_shutdown, gl_backend_newmap);
 }
 
-/*
-=============
-GL_SetupFrame
-=============
-*/
-static void GL_SetupFrame (void)
+void GL_SetupView_ViewPort (int x, int y, int width, int height)
 {
-       double xmax, ymax;
-       double fovx, fovy, zNear, zFar, aspect;
-
        if (!r_render.integer)
                return;
 
-       qglDepthFunc (GL_LEQUAL);CHECKGLERROR
+       // y is weird beause OpenGL is bottom to top, we use top to bottom
+       qglViewport(x, vid.realheight - (y + height), width, height);
+       CHECKGLERROR
+}
 
-       // set up viewpoint
-       qglMatrixMode(GL_PROJECTION);CHECKGLERROR
-       qglLoadIdentity ();CHECKGLERROR
+void GL_SetupView_Orientation_Identity (void)
+{
+       Matrix4x4_CreateIdentity(&backend_viewmatrix);
+       memset(&backend_modelmatrix, 0, sizeof(backend_modelmatrix));
+}
 
-       // y is weird beause OpenGL is bottom to top, we use top to bottom
-       qglViewport(r_refdef.x, vid.realheight - (r_refdef.y + r_refdef.height), r_refdef.width, r_refdef.height);CHECKGLERROR
+void GL_SetupView_Orientation_FromEntity (vec3_t origin, vec3_t angles)
+{
+       Matrix4x4_CreateRotate(&backend_viewmatrix, -90, 1, 0, 0);
+       Matrix4x4_ConcatRotate(&backend_viewmatrix, 90, 0, 0, 1);
+       Matrix4x4_ConcatRotate(&backend_viewmatrix, -angles[2], 1, 0, 0);
+       Matrix4x4_ConcatRotate(&backend_viewmatrix, -angles[0], 0, 1, 0);
+       Matrix4x4_ConcatRotate(&backend_viewmatrix, -angles[1], 0, 0, 1);
+       Matrix4x4_ConcatTranslate(&backend_viewmatrix, -origin[0], -origin[1], -origin[2]);
+       memset(&backend_modelmatrix, 0, sizeof(backend_modelmatrix));
+}
 
-       // depth range
-       zNear = 1.0;
-       zFar = r_mesh_farclip;
-       if (zFar < 64)
-               zFar = 64;
+void GL_SetupView_Mode_Perspective (double aspect, double fovx, double fovy, double zNear, double zFar)
+{
+       double xmax, ymax;
 
-       // fov angles
-       fovx = r_refdef.fov_x;
-       fovy = r_refdef.fov_y;
-       aspect = r_refdef.width / r_refdef.height;
+       if (!r_render.integer)
+               return;
 
+       // set up viewpoint
+       qglMatrixMode(GL_PROJECTION);CHECKGLERROR
+       qglLoadIdentity ();CHECKGLERROR
        // pyramid slopes
-       xmax = zNear * tan(fovx * M_PI / 360.0) * aspect;
+       xmax = zNear * tan(fovx * M_PI / 360.0);
        ymax = zNear * tan(fovy * M_PI / 360.0);
-
        // set view pyramid
        qglFrustum(-xmax, xmax, -ymax, ymax, zNear, zFar);CHECKGLERROR
-
        qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
+       GL_SetupView_Orientation_Identity();
+}
 
-       Matrix4x4_CreateRotate(&backend_viewmatrix, -90, 1, 0, 0);
-       Matrix4x4_ConcatRotate(&backend_viewmatrix, 90, 0, 0, 1);
-       Matrix4x4_ConcatRotate(&backend_viewmatrix, -r_refdef.viewangles[2], 1, 0, 0);
-       Matrix4x4_ConcatRotate(&backend_viewmatrix, -r_refdef.viewangles[0], 0, 1, 0);
-       Matrix4x4_ConcatRotate(&backend_viewmatrix, -r_refdef.viewangles[1], 0, 0, 1);
-       Matrix4x4_ConcatTranslate(&backend_viewmatrix, -r_refdef.vieworg[0],  -r_refdef.vieworg[1],  -r_refdef.vieworg[2]);
-       //Con_Printf("Our Matrix:\n");
-       //Matrix4x4_Print(&backend_viewmatrix);
-
-       //Matrix4x4_Transpose(&backend_glmodelviewmatrix, &backend_viewmatrix);
-       //qglLoadMatrixf(&backend_glmodelviewmatrix.m[0][0]);CHECKGLERROR
-       memset(&backend_modelmatrix, 0, sizeof(backend_modelmatrix));
+void GL_SetupView_Mode_Ortho (double x1, double y1, double x2, double y2, double zNear, double zFar)
+{
+       if (!r_render.integer)
+               return;
 
-       /*
-       // put Z going up
+       // set up viewpoint
+       qglMatrixMode(GL_PROJECTION);CHECKGLERROR
        qglLoadIdentity ();CHECKGLERROR
-       qglRotatef (-90,  1, 0, 0);CHECKGLERROR
-       qglRotatef (90,  0, 0, 1);CHECKGLERROR
-       // camera rotation
-       qglRotatef (-r_refdef.viewangles[2],  1, 0, 0);CHECKGLERROR
-       qglRotatef (-r_refdef.viewangles[0],  0, 1, 0);CHECKGLERROR
-       qglRotatef (-r_refdef.viewangles[1],  0, 0, 1);CHECKGLERROR
-       // camera location
-       qglTranslatef (-r_refdef.vieworg[0],  -r_refdef.vieworg[1],  -r_refdef.vieworg[2]);CHECKGLERROR
-       qglGetFloatv (GL_MODELVIEW_MATRIX, &gl_viewmatrix.m[0][0]);
-       Matrix4x4_Transpose(&backend_viewmatrix, &gl_viewmatrix);
-       Con_Printf("GL Matrix:\n");
-       Matrix4x4_Print(&backend_viewmatrix);
-       */
+       qglOrtho(x1, x2, y2, y1, zNear, zFar);
+       qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
+       GL_SetupView_Orientation_Identity();
 }
 
 static struct
@@ -283,6 +264,7 @@ static struct
        int clientunit;
        int texture[MAX_TEXTUREUNITS];
        float texturergbscale[MAX_TEXTUREUNITS];
+       int colorarray;
 }
 gl_state;
 
@@ -363,7 +345,6 @@ void GL_SetupTextureState(void)
        }
 }
 
-int usedarrays;
 void GL_Backend_ResetState(void)
 {
        int i;
@@ -392,8 +373,6 @@ void GL_Backend_ResetState(void)
        gl_state.depthmask = GL_TRUE;
        qglDepthMask(gl_state.depthmask);CHECKGLERROR
 
-       usedarrays = false;
-       usedarrays = true;
        qglVertexPointer(3, GL_FLOAT, sizeof(float[4]), varray_vertex);CHECKGLERROR
        qglEnableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
        if (gl_mesh_floatcolors.integer)
@@ -404,26 +383,43 @@ void GL_Backend_ResetState(void)
        {
                qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(qbyte[4]), varray_bcolor);CHECKGLERROR
        }
-       qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
+       // LordHavoc: default to color array off
+       gl_state.colorarray = false;
+       GL_Color(1, 1, 1, 1);
 
        GL_SetupTextureState();
 }
 
+void GL_UseColorArray(void)
+{
+       if (!gl_state.colorarray)
+       {
+               gl_state.colorarray = true;
+               qglEnableClientState(GL_COLOR_ARRAY);CHECKGLERROR
+       }
+}
+
+void GL_Color(float cr, float cg, float cb, float ca)
+{
+       if (gl_state.colorarray)
+       {
+               gl_state.colorarray = false;
+               qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
+       }
+       qglColor4f(cr, cg, cb, ca);
+}
+
 // called at beginning of frame
-void R_Mesh_Start(float farclip)
+void R_Mesh_Start(void)
 {
        BACKENDACTIVECHECK
 
        CHECKGLERROR
 
-       r_mesh_farclip = farclip;
-
        GL_Backend_CheckCvars();
        if (mesh_maxverts != gl_mesh_maxverts.integer)
                GL_Backend_ResizeArrays(gl_mesh_maxverts.integer);
 
-       GL_SetupFrame();
-
        GL_Backend_ResetState();
 }
 
@@ -534,7 +530,7 @@ void R_Mesh_Draw(int numverts, int numtriangles, int *elements)
 
        CHECKGLERROR
 
-       if (!gl_mesh_floatcolors.integer)
+       if (gl_state.colorarray && !gl_mesh_floatcolors.integer)
                GL_ConvertColorsFloatToByte(numverts);
        //GL_TransformVertices(numverts);
        if (!r_render.integer)
@@ -568,27 +564,18 @@ void R_Mesh_Finish(void)
                        }
                        qglBindTexture(GL_TEXTURE_2D, 0);CHECKGLERROR
 
-                       if (usedarrays)
-                       {
-                               qglClientActiveTexture(GL_TEXTURE0_ARB + i);CHECKGLERROR
-                               qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
-                       }
+                       qglClientActiveTexture(GL_TEXTURE0_ARB + i);CHECKGLERROR
+                       qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
                }
        }
        else
        {
                qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);CHECKGLERROR
                qglEnable(GL_TEXTURE_2D);CHECKGLERROR
-               if (usedarrays)
-               {
-                       qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
-               }
-       }
-       if (usedarrays)
-       {
-               qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
-               qglDisableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
+               qglDisableClientState(GL_TEXTURE_COORD_ARRAY);CHECKGLERROR
        }
+       qglDisableClientState(GL_COLOR_ARRAY);CHECKGLERROR
+       qglDisableClientState(GL_VERTEX_ARRAY);CHECKGLERROR
 
        qglDisable(GL_BLEND);CHECKGLERROR
        qglEnable(GL_DEPTH_TEST);CHECKGLERROR
@@ -596,15 +583,6 @@ void R_Mesh_Finish(void)
        qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);CHECKGLERROR
 }
 
-void R_Mesh_ClearDepth(void)
-{
-       BACKENDACTIVECHECK
-
-       R_Mesh_Finish();
-       qglClear(GL_DEPTH_BUFFER_BIT);
-       R_Mesh_Start(r_mesh_farclip);
-}
-
 void R_Mesh_Matrix(const matrix4x4_t *matrix)
 {
        if (memcmp(matrix, &backend_modelmatrix, sizeof(matrix4x4_t)))
@@ -617,40 +595,10 @@ void R_Mesh_Matrix(const matrix4x4_t *matrix)
 }
 
 // sets up the requested state
-void R_Mesh_State(const rmeshstate_t *m)
+void R_Mesh_MainState(const rmeshstate_t *m)
 {
-       int i, overbright;
-       int texturergbscale[MAX_TEXTUREUNITS];
-       float scaler;
-
        BACKENDACTIVECHECK
 
-       if (gl_backend_rebindtextures)
-       {
-               gl_backend_rebindtextures = false;
-               GL_SetupTextureState();
-       }
-
-       overbright = false;
-       scaler = 1;
-       if (m->blendfunc1 == GL_DST_COLOR)
-       {
-               // check if it is a 2x modulate with framebuffer
-               if (m->blendfunc2 == GL_SRC_COLOR)
-                       scaler *= 0.5f;
-       }
-       else if (m->blendfunc2 != GL_SRC_COLOR)
-       {
-               if (m->tex[0])
-               {
-                       overbright = m->wantoverbright && gl_combine.integer;
-                       if (overbright)
-                               scaler *= 0.25f;
-               }
-               scaler *= overbrightscale;
-       }
-       mesh_colorscale = scaler;
-
        if (gl_state.blendfunc1 != m->blendfunc1 || gl_state.blendfunc2 != m->blendfunc2)
        {
                qglBlendFunc(gl_state.blendfunc1 = m->blendfunc1, gl_state.blendfunc2 = m->blendfunc2);CHECKGLERROR
@@ -694,6 +642,20 @@ void R_Mesh_State(const rmeshstate_t *m)
        {
                qglDepthMask(gl_state.depthmask = (m->blendfunc2 == GL_ZERO || m->depthwrite));CHECKGLERROR
        }
+}
+
+void R_Mesh_TextureState(const rmeshstate_t *m)
+{
+       int i;
+       int texturergbscale[MAX_TEXTUREUNITS];
+
+       BACKENDACTIVECHECK
+
+       if (gl_backend_rebindtextures)
+       {
+               gl_backend_rebindtextures = false;
+               GL_SetupTextureState();
+       }
 
        for (i = 0;i < backendunits;i++)
        {
@@ -702,17 +664,6 @@ void R_Mesh_State(const rmeshstate_t *m)
                else
                        texturergbscale[i] = 1;
        }
-       if (overbright)
-       {
-               for (i = backendunits - 1;i >= 0;i--)
-               {
-                       if (m->tex[i])
-                       {
-                               texturergbscale[i] = 4;
-                               break;
-                       }
-               }
-       }
 
        if (backendunits > 1)
        {
@@ -773,6 +724,12 @@ void R_Mesh_State(const rmeshstate_t *m)
        }
 }
 
+void R_Mesh_State(const rmeshstate_t *m)
+{
+       R_Mesh_MainState(m);
+       R_Mesh_TextureState(m);
+}
+
 /*
 ==============================================================================
 
@@ -850,13 +807,12 @@ void SCR_UpdateScreen (void)
                Cvar_SetValueQuick(&gl_combine, 0);
 
        // lighting scale
-       overbrightscale = 1.0f / (float) (1 << v_overbrightbits.integer);
+       r_colorscale = 1.0f / (float) (1 << v_overbrightbits.integer);
 
        // lightmaps only
-       lightscalebit = v_overbrightbits.integer;
+       r_lightmapscalebit = v_overbrightbits.integer;
        if (gl_combine.integer && r_textureunits.integer > 1)
-               lightscalebit += 2;
-       lightscale = 1.0f / (float) (1 << lightscalebit);
+               r_lightmapscalebit += 2;
 
        R_TimeReport("setup");