]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
added nexuiz icon and make rules to make use of it, and now the icon is included...
[xonotic/darkplaces.git] / gl_rmain.c
index d1291faa51a0e1b00773313dd0ea6a5b2fceec74..1f504139682957dec5ec743b091593ead21cc94f 100644 (file)
@@ -69,44 +69,44 @@ matrix4x4_t r_view_matrix;
 //
 refdef_t r_refdef;
 
-cvar_t r_showtris = {0, "r_showtris", "0"};
-cvar_t r_shownormals = {0, "r_shownormals", "0"};
-cvar_t r_drawentities = {0, "r_drawentities","1"};
-cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1"};
-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_fullbrights = {CVAR_SAVE, "r_fullbrights", "1"};
-cvar_t r_drawcollisionbrushes = {0, "r_drawcollisionbrushes", "0"};
+cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"};
+cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"};
+cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
+cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
+cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
+cvar_t r_fullbright = {0, "r_fullbright","0", "make everything bright cheat (not allowed in multiplayer)"};
+cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
+cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
+cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
+cvar_t r_drawcollisionbrushes = {0, "r_drawcollisionbrushes", "0", "draws collision brushes in quake3 maps (mode 1), mode 2 disables rendering of world (trippy!)"};
 
-cvar_t gl_fogenable = {0, "gl_fogenable", "0"};
-cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25"};
-cvar_t gl_fogred = {0, "gl_fogred","0.3"};
-cvar_t gl_foggreen = {0, "gl_foggreen","0.3"};
-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 gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
+cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
+cvar_t gl_fogred = {0, "gl_fogred","0.3", "nehahra fog color red value (for Nehahra compatibility only)"};
+cvar_t gl_foggreen = {0, "gl_foggreen","0.3", "nehahra fog color green value (for Nehahra compatibility only)"};
+cvar_t gl_fogblue = {0, "gl_fogblue","0.3", "nehahra fog color blue value (for Nehahra compatibility only)"};
+cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Nehahra compatibility only)"};
+cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"};
 
-cvar_t r_textureunits = {0, "r_textureunits", "32"};
+cvar_t r_textureunits = {0, "r_textureunits", "32", "number of hardware texture units reported by driver (note: setting this to 1 turns off gl_combine)"};
 
-cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1"};
-cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1"};
-cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1"};
+cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1", "enables animation smoothing on sprites (requires r_lerpmodels 1)"};
+cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"};
+cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"};
 
-cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0"};
-cvar_t r_bloom_intensity = {CVAR_SAVE, "r_bloom_intensity", "1.5"};
-cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4"};
-cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320"};
-cvar_t r_bloom_power = {CVAR_SAVE, "r_bloom_power", "2"};
+cvar_t r_bloom = {CVAR_SAVE, "r_bloom", "0", "enables bloom effect (makes bright pixels affect neighboring pixels)"};
+cvar_t r_bloom_intensity = {CVAR_SAVE, "r_bloom_intensity", "1.5", "how bright the glow is"};
+cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "4", "how large the glow is"};
+cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320", "what resolution to perform the bloom effect at (independent of screen resolution)"};
+cvar_t r_bloom_power = {CVAR_SAVE, "r_bloom_power", "2", "how much to darken the image before blurring to make the bloom effect"};
 
-cvar_t r_smoothnormals_areaweighting = {0, "r_smoothnormals_areaweighting", "1"};
+cvar_t r_smoothnormals_areaweighting = {0, "r_smoothnormals_areaweighting", "1", "uses significantly faster (and supposedly higher quality) area-weighted vertex normals and tangent vectors rather than summing normalized triangle normals and tangents"};
 
-cvar_t developer_texturelogging = {0, "developer_texturelogging", "0"};
+cvar_t developer_texturelogging = {0, "developer_texturelogging", "0", "produces a textures.log file containing names of skins and map textures the engine tried to load"};
 
-cvar_t gl_lightmaps = {0, "gl_lightmaps", "0"};
+cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"};
 
-cvar_t r_test = {0, "r_test", "0"}; // used for testing renderer code changes, otherwise does nothing
+cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"}; // used for testing renderer code changes, otherwise does nothing
 
 rtexturepool_t *r_main_texturepool;
 rtexture_t *r_bloom_texture_screen;
@@ -1097,7 +1097,58 @@ void R_RenderView(void)
        GL_ScissorTest(false);
 }
 
+//[515]: csqc
+void CSQC_R_ClearScreen (void)
+{
+       if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
+               return; //Host_Error ("R_RenderView: NULL worldmodel");
+
+       r_view_width = bound(0, r_refdef.width, vid.width);
+       r_view_height = bound(0, r_refdef.height, vid.height);
+       r_view_depth = 1;
+       r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width);
+       r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height);
+       r_view_z = 0;
+       r_view_matrix = r_refdef.viewentitymatrix;
+       GL_ColorMask(r_refdef.colormask[0], r_refdef.colormask[1], r_refdef.colormask[2], 1);
+       r_rtworld = r_shadow_realtime_world.integer;
+       r_rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil;
+       r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer;
+       r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil;
+       r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
+
+       // GL is weird because it's bottom to top, r_view_y is top to bottom
+       qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height);
+       GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height);
+       GL_ScissorTest(true);
+       GL_DepthMask(true);
+       R_ClearScreen();
+       R_Textures_Frame();
+       R_UpdateFog();
+       R_TimeReport("setup");
+}
+
+//[515]: csqc
+void CSQC_R_RenderScene (void)
+{
+       qglDepthFunc(GL_LEQUAL);
+       qglPolygonOffset(0, 0);
+       qglEnable(GL_POLYGON_OFFSET_FILL);
+
+       R_RenderScene();
+
+       qglPolygonOffset(0, 0);
+       qglDisable(GL_POLYGON_OFFSET_FILL);
+
+       R_BlendView();
+       R_TimeReport("blendview");
+
+       GL_Scissor(0, 0, vid.width, vid.height);
+       GL_ScissorTest(false);
+}
+
 extern void R_DrawLightningBeams (void);
+extern void VM_AddPolygonsToMeshQueue (void);
 void R_RenderScene(void)
 {
        // don't let sound skip if going slow
@@ -1136,21 +1187,24 @@ void R_RenderScene(void)
        if (r_refdef.extraupdate)
                S_ExtraUpdate ();
 
-       GL_ShowTrisColor(0.025, 0.025, 0, 1);
-       if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
+       if (cl.csqc_vidvars.drawworld)
        {
-               r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
-               R_TimeReport("worldsky");
-       }
+               GL_ShowTrisColor(0.025, 0.025, 0, 1);
+               if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
+               {
+                       r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
+                       R_TimeReport("worldsky");
+               }
 
-       if (R_DrawBrushModelsSky())
-               R_TimeReport("bmodelsky");
+               if (R_DrawBrushModelsSky())
+                       R_TimeReport("bmodelsky");
 
-       GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
-       if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
-       {
-               r_refdef.worldmodel->Draw(r_refdef.worldentity);
-               R_TimeReport("world");
+               GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
+               if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
+               {
+                       r_refdef.worldmodel->Draw(r_refdef.worldentity);
+                       R_TimeReport("world");
+               }
        }
 
        // don't let sound skip if going slow
@@ -1176,23 +1230,33 @@ void R_RenderScene(void)
 
        GL_ShowTrisColor(0.1, 0, 0, 1);
 
-       R_DrawLightningBeams();
-       R_TimeReport("lightning");
+       if (cl.csqc_vidvars.drawworld)
+       {
+               R_DrawLightningBeams();
+               R_TimeReport("lightning");
 
-       R_DrawParticles();
-       R_TimeReport("particles");
+               R_DrawParticles();
+               R_TimeReport("particles");
 
-       R_DrawExplosions();
-       R_TimeReport("explosions");
+               R_DrawExplosions();
+               R_TimeReport("explosions");
+       }
 
        R_MeshQueue_RenderTransparent();
        R_TimeReport("drawtrans");
 
-       R_DrawCoronas();
-       R_TimeReport("coronas");
+       if (cl.csqc_vidvars.drawworld)
+       {
+               R_DrawCoronas();
+               R_TimeReport("coronas");
+       }
+       if(cl.csqc_vidvars.drawcrosshair)
+       {
+               R_DrawWorldCrosshair();
+               R_TimeReport("crosshair");
+       }
 
-       R_DrawWorldCrosshair();
-       R_TimeReport("crosshair");
+       VM_AddPolygonsToMeshQueue();
 
        R_MeshQueue_Render();
        R_MeshQueue_EndScene();
@@ -1281,9 +1345,8 @@ float nomodelcolor4f[6*4] =
        0.5f, 0.0f, 0.0f, 1.0f
 };
 
-void R_DrawNoModelCallback(const void *calldata1, int calldata2)
+void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
 {
-       const entity_render_t *ent = (entity_render_t *)calldata1;
        int i;
        float f1, f2, *c;
        float color4f[6*4];
@@ -1339,7 +1402,7 @@ void R_DrawNoModelCallback(const void *calldata1, int calldata2)
 void R_DrawNoModel(entity_render_t *ent)
 {
        //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1))
-               R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModelCallback, ent, 0);
+               R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawNoModel_TransparentCallback, ent, 0, r_shadow_rtlight);
        //else
        //      R_DrawNoModelCallback(ent, 0);
 }
@@ -1507,7 +1570,6 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
 {
        // FIXME: identify models using a better check than ent->model->brush.shadowmesh
        //int lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2;
-       float currentalpha;
 
        {
                texture_t *texture = t;
@@ -1530,14 +1592,14 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
        }
 
        t->currentmaterialflags = t->basematerialflags;
-       currentalpha = ent->alpha;
+       t->currentalpha = ent->alpha;
        if (t->basematerialflags & MATERIALFLAG_WATERALPHA)
-               currentalpha *= r_wateralpha.value;
+               t->currentalpha *= r_wateralpha.value;
        if (!(ent->flags & RENDER_LIGHT))
                t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
        if (ent->effects & EF_ADDITIVE)
                t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_TRANSPARENT;
-       else if (currentalpha < 1)
+       else if (t->currentalpha < 1)
                t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_TRANSPARENT;
        if (ent->effects & EF_NODEPTHTEST)
                t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST;
@@ -1583,14 +1645,15 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                                int layerflags = 0;
                                if (fogenabled && (t->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
                                        layerflags |= TEXTURELAYERFLAG_FOGDARKEN;
-                               currentbasetexture = (ent->colormap < 0 && t->skin.merged) ? t->skin.merged : t->skin.base;
+                               currentbasetexture = (VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) < (1.0f / 1048576.0f) && t->skin.merged) ? t->skin.merged : t->skin.base;
                                if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
                                {
-                                       R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0], ent->colormod[1], ent->colormod[2], currentalpha);
-                                       if (ent->colormap >= 0 && t->skin.pants)
-                                               R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.pants, &t->currenttexmatrix, ent->colormap_pantscolor[0], ent->colormap_pantscolor[1], ent->colormap_pantscolor[2], currentalpha);
-                                       if (ent->colormap >= 0 && t->skin.shirt)
-                                               R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0], ent->colormap_shirtcolor[1], ent->colormap_shirtcolor[2], currentalpha);
+                                       // fullbright is not affected by r_lightmapintensity
+                                       R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0], ent->colormod[1], ent->colormod[2], t->currentalpha);
+                                       if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
+                                               R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * ent->colormod[0], ent->colormap_pantscolor[1] * ent->colormod[1], ent->colormap_pantscolor[2] * ent->colormod[2], t->currentalpha);
+                                       if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
+                                               R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * ent->colormod[0], ent->colormap_shirtcolor[1] * ent->colormod[1], ent->colormap_shirtcolor[2] * ent->colormod[2], t->currentalpha);
                                }
                                else
                                {
@@ -1601,32 +1664,30 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                                        // applied to the color
                                        if (ent->model->type == mod_brushq3)
                                                colorscale *= r_refdef.lightstylevalue[0] * (1.0f / 256.0f);
-                                       // transparent and fullbright are not affected by r_lightmapintensity
-                                       if (!(t->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
-                                               colorscale *= r_lightmapintensity;
+                                       colorscale *= r_lightmapintensity;
                                        if (r_textureunits.integer >= 2 && gl_combine.integer)
-                                               R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE_COMBINE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, currentalpha);
+                                               R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE_COMBINE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha);
                                        else if ((t->currentmaterialflags & MATERIALFLAG_TRANSPARENT) == 0)
-                                               R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale * 0.5f, ent->colormod[1] * colorscale * 0.5f, ent->colormod[2] * colorscale * 0.5f, currentalpha);
+                                               R_Texture_AddLayer(t, true, GL_ONE, GL_ZERO, TEXTURELAYERTYPE_LITTEXTURE_MULTIPASS, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale * 0.5f, ent->colormod[1] * colorscale * 0.5f, ent->colormod[2] * colorscale * 0.5f, t->currentalpha);
                                        else
-                                               R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, currentalpha);
+                                               R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * colorscale, ent->colormod[1] * colorscale, ent->colormod[2] * colorscale, t->currentalpha);
                                        if (r_ambient.value >= (1.0f/64.0f))
-                                               R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * r_ambient.value * (1.0f / 64.0f), ent->colormod[1] * r_ambient.value * (1.0f / 64.0f), ent->colormod[2] * r_ambient.value * (1.0f / 64.0f), currentalpha);
-                                       if (ent->colormap >= 0 && t->skin.pants)
+                                               R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, currentbasetexture, &t->currenttexmatrix, ent->colormod[0] * r_ambient.value * (1.0f / 64.0f), ent->colormod[1] * r_ambient.value * (1.0f / 64.0f), ent->colormod[2] * r_ambient.value * (1.0f / 64.0f), t->currentalpha);
+                                       if (VectorLength2(ent->colormap_pantscolor) >= (1.0f / 1048576.0f) && t->skin.pants)
                                        {
-                                               R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, t->skin.pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * colorscale, ent->colormap_pantscolor[1] * colorscale, ent->colormap_pantscolor[2] * colorscale, currentalpha);
+                                               R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, t->skin.pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * ent->colormod[0] * colorscale, ent->colormap_pantscolor[1] * ent->colormod[1] * colorscale, ent->colormap_pantscolor[2]  * ent->colormod[2] * colorscale, t->currentalpha);
                                                if (r_ambient.value >= (1.0f/64.0f))
-                                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * r_ambient.value * (1.0f / 64.0f), ent->colormap_pantscolor[1] * r_ambient.value * (1.0f / 64.0f), ent->colormap_pantscolor[2] * r_ambient.value * (1.0f / 64.0f), currentalpha);
+                                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.pants, &t->currenttexmatrix, ent->colormap_pantscolor[0] * ent->colormod[0] * r_ambient.value * (1.0f / 64.0f), ent->colormap_pantscolor[1] * ent->colormod[1] * r_ambient.value * (1.0f / 64.0f), ent->colormap_pantscolor[2] * ent->colormod[2] * r_ambient.value * (1.0f / 64.0f), t->currentalpha);
                                        }
-                                       if (ent->colormap >= 0 && t->skin.shirt)
+                                       if (VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f) && t->skin.shirt)
                                        {
-                                               R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, t->skin.shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * colorscale, ent->colormap_shirtcolor[1] * colorscale, ent->colormap_shirtcolor[2] * colorscale, currentalpha);
+                                               R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_LITTEXTURE_VERTEX, t->skin.shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * ent->colormod[0] * colorscale, ent->colormap_shirtcolor[1] * ent->colormod[1] * colorscale, ent->colormap_shirtcolor[2] * ent->colormod[2] * colorscale, t->currentalpha);
                                                if (r_ambient.value >= (1.0f/64.0f))
-                                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * r_ambient.value * (1.0f / 64.0f), ent->colormap_shirtcolor[1] * r_ambient.value * (1.0f / 64.0f), ent->colormap_shirtcolor[2] * r_ambient.value * (1.0f / 64.0f), currentalpha);
+                                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.shirt, &t->currenttexmatrix, ent->colormap_shirtcolor[0] * ent->colormod[0] * r_ambient.value * (1.0f / 64.0f), ent->colormap_shirtcolor[1] * ent->colormod[1] * r_ambient.value * (1.0f / 64.0f), ent->colormap_shirtcolor[2] * ent->colormod[2] * r_ambient.value * (1.0f / 64.0f), t->currentalpha);
                                        }
                                }
                                if (t->skin.glow != NULL)
-                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.glow, &t->currenttexmatrix, 1, 1, 1, currentalpha);
+                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, GL_ONE, TEXTURELAYERTYPE_TEXTURE, t->skin.glow, &t->currenttexmatrix, 1, 1, 1, t->currentalpha);
                                if (fogenabled && !(t->currentmaterialflags & MATERIALFLAG_ADD))
                                {
                                        // if this is opaque use alpha blend which will darken the earlier
@@ -1640,7 +1701,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                                        // were darkened by fog already, and we should not add fog color
                                        // (because the background was not darkened, there is no fog color
                                        // that was lost behind it).
-                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_TRANSPARENT) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->skin.fog, &r_identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], currentalpha);
+                                       R_Texture_AddLayer(t, false, GL_SRC_ALPHA, (t->currentmaterialflags & MATERIALFLAG_TRANSPARENT) ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA, TEXTURELAYERTYPE_FOG, t->skin.fog, &r_identitymatrix, fogcolor[0], fogcolor[1], fogcolor[2], t->currentalpha);
                                }
                        }
                }
@@ -1883,7 +1944,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
        // FIXME: identify models using a better check than ent->model->brush.shadowmesh
        lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2;
        GL_DepthTest(!(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
-       if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+       if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE))
                qglDisable(GL_CULL_FACE);
        if (texture->currentnumlayers)
        {
@@ -2177,14 +2238,13 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text
                        }
                }
        }
-       if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+       if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE))
                qglEnable(GL_CULL_FACE);
 }
 
-static void RSurfShader_Transparent_Callback(const void *calldata1, int calldata2)
+static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight)
 {
-       const entity_render_t *ent = (entity_render_t *)calldata1;
-       const msurface_t *surface = ent->model->data_surfaces + calldata2;
+       const msurface_t *surface = ent->model->data_surfaces + surfacenumber;
        vec3_t modelorg;
        texture_t *texture;
 
@@ -2215,7 +2275,7 @@ void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int tex
                                tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
                                tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
                                Matrix4x4_Transform(&ent->matrix, tempcenter, center);
-                               R_MeshQueue_AddTransparent(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, RSurfShader_Transparent_Callback, ent, surface - ent->model->data_surfaces);
+                               R_MeshQueue_AddTransparent(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, R_DrawSurface_TransparentCallback, ent, surface - ent->model->data_surfaces, r_shadow_rtlight);
                        }
                }
        }