]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
optimizations to rendering
[xonotic/darkplaces.git] / gl_rmain.c
index 3c20a454da7cb53a66988375a48fd43b87d3acf4..d0a46fa24af4c1ed6422a427904fdfcf8020b728 100644 (file)
@@ -21,8 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 
-entity_render_t *currentrenderentity;
-
 // used for dlight push checking and other things
 int r_framecount;
 
@@ -57,7 +55,6 @@ cvar_t r_speeds = {0, "r_speeds","0"};
 cvar_t r_fullbright = {0, "r_fullbright","0"};
 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1"};
 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1"};
-cvar_t r_waterripple = {CVAR_SAVE, "r_waterripple","0"};
 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"};
 
 cvar_t gl_fogenable = {0, "gl_fogenable", "0"};
@@ -68,7 +65,34 @@ cvar_t gl_fogblue = {0, "gl_fogblue","0.3"};
 cvar_t gl_fogstart = {0, "gl_fogstart", "0"};
 cvar_t gl_fogend = {0, "gl_fogend","0"};
 
-cvar_t r_multitexture = {0, "r_multitexture", "1"};
+cvar_t r_textureunits = {0, "r_textureunits", "32"};
+
+void R_ModulateColors(float *in, float *out, int verts, float r, float g, float b)
+{
+       int i;
+       for (i = 0;i < verts;i++)
+       {
+               out[0] = in[0] * r;
+               out[1] = in[1] * g;
+               out[2] = in[2] * b;
+               out[3] = in[3];
+               in += 4;
+               out += 4;
+       }
+}
+
+void R_FillColors(float *out, int verts, float r, float g, float b, float a)
+{
+       int i;
+       for (i = 0;i < verts;i++)
+       {
+               out[0] = r;
+               out[1] = g;
+               out[2] = b;
+               out[3] = a;
+               out += 4;
+       }
+}
 
 /*
 ====================
@@ -240,9 +264,8 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable (&r_fullbrights);
        Cvar_RegisterVariable (&r_wateralpha);
        Cvar_RegisterVariable (&r_dynamic);
-       Cvar_RegisterVariable (&r_waterripple);
        Cvar_RegisterVariable (&r_fullbright);
-       Cvar_RegisterVariable (&r_multitexture);
+       Cvar_RegisterVariable (&r_textureunits);
        if (gamemode == GAME_NEHAHRA)
                Cvar_SetValue("r_fullbrights", 0);
        R_RegisterModule("GL_Main", gl_main_start, gl_main_shutdown, gl_main_newmap);
@@ -326,6 +349,7 @@ void Render_Init(void)
        R_Textures_Init();
        Mod_RenderInit();
        gl_backend_init();
+       R_MeshQueue_Init();
        GL_Draw_Init();
        GL_Main_Init();
        GL_Models_Init();
@@ -363,53 +387,65 @@ static void R_MarkEntities (void)
 {
        int i;
        vec3_t v;
+       entity_render_t *ent;
 
-       if (!r_drawentities.integer)
-               return;
+       ent = &cl_entities[0].render;
+       Matrix4x4_CreateIdentity(&ent->matrix);
+       Matrix4x4_CreateIdentity(&ent->inversematrix);
 
        R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
 
+       if (!r_drawentities.integer)
+               return;
+
        for (i = 0;i < r_refdef.numentities;i++)
        {
-               currentrenderentity = r_refdef.entities[i];
-               Mod_CheckLoaded(currentrenderentity->model);
+               ent = r_refdef.entities[i];
+               Mod_CheckLoaded(ent->model);
 
                // move view-relative models to where they should be
-               if (currentrenderentity->flags & RENDER_VIEWMODEL)
+               if (ent->flags & RENDER_VIEWMODEL)
                {
                        // remove flag so it will not be repeated incase RelinkEntities is not called again for a while
-                       currentrenderentity->flags -= RENDER_VIEWMODEL;
+                       ent->flags -= RENDER_VIEWMODEL;
                        // transform origin
-                       VectorCopy(currentrenderentity->origin, v);
-                       currentrenderentity->origin[0] = v[0] * vpn[0] + v[1] * vright[0] + v[2] * vup[0] + r_origin[0];
-                       currentrenderentity->origin[1] = v[0] * vpn[1] + v[1] * vright[1] + v[2] * vup[1] + r_origin[1];
-                       currentrenderentity->origin[2] = v[0] * vpn[2] + v[1] * vright[2] + v[2] * vup[2] + r_origin[2];
+                       VectorCopy(ent->origin, v);
+                       ent->origin[0] = v[0] * vpn[0] + v[1] * vright[0] + v[2] * vup[0] + r_origin[0];
+                       ent->origin[1] = v[0] * vpn[1] + v[1] * vright[1] + v[2] * vup[1] + r_origin[1];
+                       ent->origin[2] = v[0] * vpn[2] + v[1] * vright[2] + v[2] * vup[2] + r_origin[2];
                        // adjust angles
-                       VectorAdd(currentrenderentity->angles, r_refdef.viewangles, currentrenderentity->angles);
+                       VectorAdd(ent->angles, r_refdef.viewangles, ent->angles);
                }
 
-               if (currentrenderentity->angles[0] || currentrenderentity->angles[2])
+               if (ent->angles[0] || ent->angles[2])
                {
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->rotatedmins, currentrenderentity->mins);
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->rotatedmaxs, currentrenderentity->maxs);
+                       VectorMA(ent->origin, ent->scale, ent->model->rotatedmins, ent->mins);
+                       VectorMA(ent->origin, ent->scale, ent->model->rotatedmaxs, ent->maxs);
                }
-               else if (currentrenderentity->angles[1])
+               else if (ent->angles[1])
                {
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->yawmins, currentrenderentity->mins);
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->yawmaxs, currentrenderentity->maxs);
+                       VectorMA(ent->origin, ent->scale, ent->model->yawmins, ent->mins);
+                       VectorMA(ent->origin, ent->scale, ent->model->yawmaxs, ent->maxs);
                }
                else
                {
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->normalmins, currentrenderentity->mins);
-                       VectorMA(currentrenderentity->origin, currentrenderentity->scale, currentrenderentity->model->normalmaxs, currentrenderentity->maxs);
+                       VectorMA(ent->origin, ent->scale, ent->model->normalmins, ent->mins);
+                       VectorMA(ent->origin, ent->scale, ent->model->normalmaxs, ent->maxs);
                }
-               if (R_VisibleCullBox(currentrenderentity->mins, currentrenderentity->maxs))
+               if (R_VisibleCullBox(ent->mins, ent->maxs))
                        continue;
 
-               R_LerpAnimation(currentrenderentity);
-               currentrenderentity->visframe = r_framecount;
+               VectorCopy(ent->angles, v);
+               if (ent->model->type != mod_brush)
+                       v[0] = -v[0];
+               Matrix4x4_CreateFromQuakeEntity(&ent->matrix, ent->origin[0], ent->origin[1], ent->origin[2], v[0], v[1], v[2], ent->scale);
+               Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix);
+               R_LerpAnimation(ent);
+               ent->visframe = r_framecount;
 
-               R_FarClip_Box(currentrenderentity->mins, currentrenderentity->maxs);
+               R_FarClip_Box(ent->mins, ent->maxs);
+
+               R_UpdateEntLights(ent);
        }
 }
 
@@ -417,6 +453,7 @@ static void R_MarkEntities (void)
 int R_DrawBModelSky (void)
 {
        int i, sky;
+       entity_render_t *ent;
 
        if (!r_drawentities.integer)
                return false;
@@ -424,10 +461,10 @@ int R_DrawBModelSky (void)
        sky = false;
        for (i = 0;i < r_refdef.numentities;i++)
        {
-               currentrenderentity = r_refdef.entities[i];
-               if (currentrenderentity->visframe == r_framecount && currentrenderentity->model->DrawSky)
+               ent = r_refdef.entities[i];
+               if (ent->visframe == r_framecount && ent->model->DrawSky)
                {
-                       currentrenderentity->model->DrawSky();
+                       ent->model->DrawSky(ent);
                        sky = true;
                }
        }
@@ -437,15 +474,16 @@ int R_DrawBModelSky (void)
 void R_DrawModels (void)
 {
        int i;
+       entity_render_t *ent;
 
        if (!r_drawentities.integer)
                return;
 
        for (i = 0;i < r_refdef.numentities;i++)
        {
-               currentrenderentity = r_refdef.entities[i];
-               if (currentrenderentity->visframe == r_framecount && currentrenderentity->model->Draw)
-                       currentrenderentity->model->Draw();
+               ent = r_refdef.entities[i];
+               if (ent->visframe == r_framecount && ent->model->Draw)
+                       ent->model->Draw(ent);
        }
 }
 
@@ -456,16 +494,18 @@ R_DrawViewModel
 */
 void R_DrawViewModel (void)
 {
+       entity_render_t *ent;
+
        // FIXME: move these checks to client
        if (!r_drawviewmodel.integer || chase_active.integer || envmap || !r_drawentities.integer || cl.items & IT_INVISIBILITY || cl.stats[STAT_HEALTH] <= 0 || !cl.viewent.render.model)
                return;
 
-       currentrenderentity = &cl.viewent.render;
-       Mod_CheckLoaded(currentrenderentity->model);
+       ent = &cl.viewent.render;
+       Mod_CheckLoaded(ent->model);
 
-       R_LerpAnimation(currentrenderentity);
+       R_LerpAnimation(ent);
 
-       currentrenderentity->model->Draw();
+       ent->model->Draw(ent);
 }
 
 static void R_SetFrustum (void)
@@ -507,8 +547,6 @@ static void R_SetupFrame (void)
                if (r_ambient.value != 0)
                        Cvar_Set ("r_ambient", "0");
        }
-       if (r_multitexture.integer && gl_textureunits < 2)
-               Cvar_SetValue("r_multitexture", 0);
 
        r_framecount++;
 
@@ -525,42 +563,43 @@ static void R_SetupFrame (void)
 }
 
 
-static int blendviewpolyindex[3] = {0, 1, 2};
-
 static void R_BlendView(void)
 {
-       rmeshinfo_t m;
-       float tvxyz[3][4], r;
+       rmeshbufferinfo_t m;
+       float r;
 
        if (r_refdef.viewblend[3] < 0.01f)
                return;
 
        memset(&m, 0, sizeof(m));
-       m.transparent = false;
        m.blendfunc1 = GL_SRC_ALPHA;
        m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
        m.depthdisable = true; // magic
        m.numtriangles = 1;
        m.numverts = 3;
-       m.index = blendviewpolyindex;
-       m.vertex = &tvxyz[0][0];
-       m.vertexstep = sizeof(float[4]);
-       m.cr = r_refdef.viewblend[0];
-       m.cg = r_refdef.viewblend[1];
-       m.cb = r_refdef.viewblend[2];
-       m.ca = r_refdef.viewblend[3];
-       r = 64000;
-       tvxyz[0][0] = r_origin[0] + vpn[0] * 1.5 - vright[0] * r - vup[0] * r;
-       tvxyz[0][1] = r_origin[1] + vpn[1] * 1.5 - vright[1] * r - vup[1] * r;
-       tvxyz[0][2] = r_origin[2] + vpn[2] * 1.5 - vright[2] * r - vup[2] * r;
-       r *= 3;
-       tvxyz[1][0] = tvxyz[0][0] + vup[0] * r;
-       tvxyz[1][1] = tvxyz[0][1] + vup[1] * r;
-       tvxyz[1][2] = tvxyz[0][2] + vup[2] * r;
-       tvxyz[2][0] = tvxyz[0][0] + vright[0] * r;
-       tvxyz[2][1] = tvxyz[0][1] + vright[1] * r;
-       tvxyz[2][2] = tvxyz[0][2] + vright[2] * r;
-       R_Mesh_Draw(&m);
+       Matrix4x4_CreateIdentity(&m.matrix);
+       if (R_Mesh_Draw_GetBuffer(&m, false))
+       {
+               m.index[0] = 0;
+               m.index[1] = 1;
+               m.index[2] = 2;
+               m.color[0] = m.color[4] = m.color[8] = r_refdef.viewblend[0];
+               m.color[1] = m.color[5] = m.color[9] = r_refdef.viewblend[1];
+               m.color[2] = m.color[6] = m.color[10] = r_refdef.viewblend[2];
+               m.color[3] = m.color[7] = m.color[11] = r_refdef.viewblend[3];
+               r = 64000;
+               m.vertex[0] = r_origin[0] + vpn[0] * 1.5 - vright[0] * r - vup[0] * r;
+               m.vertex[1] = r_origin[1] + vpn[1] * 1.5 - vright[1] * r - vup[1] * r;
+               m.vertex[2] = r_origin[2] + vpn[2] * 1.5 - vright[2] * r - vup[2] * r;
+               r *= 3;
+               m.vertex[4] = m.vertex[0] + vup[0] * r;
+               m.vertex[5] = m.vertex[1] + vup[1] * r;
+               m.vertex[6] = m.vertex[2] + vup[2] * r;
+               m.vertex[8] = m.vertex[0] + vright[0] * r;
+               m.vertex[9] = m.vertex[1] + vright[1] * r;
+               m.vertex[10] = m.vertex[2] + vright[2] * r;
+               R_Mesh_Render();
+       }
 }
 
 /*
@@ -572,6 +611,7 @@ r_refdef must be set before the first call
 */
 void R_RenderView (void)
 {
+       entity_render_t *world = &cl_entities[0].render;
        if (!cl.worldmodel)
                return; //Host_Error ("R_RenderView: NULL worldmodel");
 
@@ -589,19 +629,22 @@ void R_RenderView (void)
 
        R_TimeReport("setup");
 
-       R_DrawWorld();
+       R_DrawWorld(world);
        R_TimeReport("worldnode");
 
        R_MarkEntities();
        R_TimeReport("markentity");
 
-       R_MarkWorldLights();
+       R_SurfMarkLights(world);
        R_TimeReport("marklights");
 
        r_farclip = R_FarClip_Finish() + 256.0f;
 
        R_Mesh_Start(r_farclip);
 
+       R_MeshQueue_BeginScene();
+
+
        if (skyrendermasked)
        {
                if (R_DrawBModelSky())
@@ -613,17 +656,16 @@ void R_RenderView (void)
                R_TimeReport("viewmodel");
        }
 
-       R_SetupForWorldRendering();
-       R_PrepareSurfaces();
+       R_PrepareSurfaces(world);
        R_TimeReport("surfprep");
 
-       R_DrawSurfaces(SHADERSTAGE_SKY);
-       R_DrawSurfaces(SHADERSTAGE_NORMAL);
+       R_DrawSurfaces(world, SHADERSTAGE_SKY);
+       R_DrawSurfaces(world, SHADERSTAGE_NORMAL);
        R_TimeReport("surfdraw");
 
        if (r_drawportals.integer)
        {
-               R_DrawPortals();
+               R_DrawPortals(world);
                R_TimeReport("portals");
        }
 
@@ -646,20 +688,22 @@ void R_RenderView (void)
        R_DrawExplosions();
        R_TimeReport("explosions");
 
-       // draw transparent meshs
-       R_Mesh_AddTransparent();
+       R_MeshQueue_RenderTransparent();
        R_TimeReport("addtrans");
 
        R_DrawCoronas();
        R_TimeReport("coronas");
 
+       R_DrawCrosshair();
+       R_TimeReport("crosshair");
+
        R_BlendView();
        R_TimeReport("blendview");
 
-       R_DrawCrosshair();
-       R_TimeReport("crosshair");
+       R_MeshQueue_Render();
+
+       R_MeshQueue_EndScene();
 
-       // render any queued meshs
        R_Mesh_Finish();
        R_TimeReport("meshfinish");
 }