]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
Fixed a bug in the r_shadow light entity parser which caused it to not read in
[xonotic/darkplaces.git] / r_shadow.c
index bee2bf6e1181bc7de5f5d136d58880aa89dda335..d9553cb9cee06866e1a052f2f647c170dd86ceb9 100644 (file)
@@ -220,10 +220,10 @@ cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1"};
 cvar_t r_shadow_visiblelighting = {0, "r_shadow_visiblelighting", "0"};
 cvar_t r_shadow_visiblevolumes = {0, "r_shadow_visiblevolumes", "0"};
 cvar_t r_shadow_glsl = {0, "r_shadow_glsl", "1"};
 cvar_t r_shadow_visiblelighting = {0, "r_shadow_visiblelighting", "0"};
 cvar_t r_shadow_visiblevolumes = {0, "r_shadow_visiblevolumes", "0"};
 cvar_t r_shadow_glsl = {0, "r_shadow_glsl", "1"};
-cvar_t r_shadow_glsl_offsetmapping = {0, "r_shadow_glsl_offsetmapping", "1"};
+cvar_t r_shadow_glsl_offsetmapping = {0, "r_shadow_glsl_offsetmapping", "0"};
 cvar_t r_shadow_glsl_offsetmapping_scale = {0, "r_shadow_glsl_offsetmapping_scale", "-0.04"};
 cvar_t r_shadow_glsl_offsetmapping_bias = {0, "r_shadow_glsl_offsetmapping_bias", "0.04"};
 cvar_t r_shadow_glsl_offsetmapping_scale = {0, "r_shadow_glsl_offsetmapping_scale", "-0.04"};
 cvar_t r_shadow_glsl_offsetmapping_bias = {0, "r_shadow_glsl_offsetmapping_bias", "0.04"};
-cvar_t r_shadow_glsl_geforcefxlowquality = {0, "r_shadow_glsl_geforcefxlowquality", "1"};
+cvar_t r_shadow_glsl_usehalffloat = {0, "r_shadow_glsl_usehalffloat", "0"};
 cvar_t r_shadow_glsl_surfacenormalize = {0, "r_shadow_glsl_surfacenormalize", "1"};
 cvar_t gl_ext_stenciltwoside = {0, "gl_ext_stenciltwoside", "1"};
 cvar_t r_editlights = {0, "r_editlights", "0"};
 cvar_t r_shadow_glsl_surfacenormalize = {0, "r_shadow_glsl_surfacenormalize", "1"};
 cvar_t gl_ext_stenciltwoside = {0, "gl_ext_stenciltwoside", "1"};
 cvar_t r_editlights = {0, "r_editlights", "0"};
@@ -427,9 +427,9 @@ const char *builtinshader_light_frag =
 void r_shadow_start(void)
 {
        int i;
 void r_shadow_start(void)
 {
        int i;
-       // if not a GeForce FX, turn off the lowquality cvar
-       if (strncmp(gl_renderer, "GeForce FX ", strlen("GeForce FX ")))
-               Cvar_SetValue("r_shadow_glsl_geforcefxlowquality", 0);
+       // use half float math where available (speed gain on NVIDIA GFFX and GF6)
+       if (gl_support_half_float)
+               Cvar_SetValue("r_shadow_glsl_usehalffloat", 1);
        // allocate vertex processing arrays
        numcubemaps = 0;
        r_shadow_attenuation2dtexture = NULL;
        // allocate vertex processing arrays
        numcubemaps = 0;
        r_shadow_attenuation2dtexture = NULL;
@@ -505,7 +505,7 @@ void r_shadow_start(void)
                        r_shadow_program_light[i] = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, fragstrings_count, fragstrings_list);
                        if (!r_shadow_program_light[i])
                        {
                        r_shadow_program_light[i] = GL_Backend_CompileProgram(vertstrings_count, vertstrings_list, fragstrings_count, fragstrings_list);
                        if (!r_shadow_program_light[i])
                        {
-                               Con_Printf("permutation %s %s %s %s failed for shader %s, some features may not work properly!\n", i & 1 ? "specular" : "", i & 2 ? "fog" : "", i & 4 ? "cubefilter" : "", i & 8 ? "offsetmapping" : "", "glsl/light");
+                               Con_Printf("permutation %s %s %s %s %s %s failed for shader %s, some features may not work properly!\n", i & 1 ? "specular" : "", i & 2 ? "fog" : "", i & 4 ? "cubefilter" : "", i & 8 ? "offsetmapping" : "", i & 16 ? "surfacenormalize" : "", i & 32 ? "geforcefx" : "", "glsl/light");
                                continue;
                        }
                        qglUseProgramObjectARB(r_shadow_program_light[i]);
                                continue;
                        }
                        qglUseProgramObjectARB(r_shadow_program_light[i]);
@@ -620,7 +620,7 @@ void R_Shadow_Help_f(void)
 "r_shadow_glsl_offsetmapping : enables Offset Mapping bumpmap enhancement\n"
 "r_shadow_glsl_offsetmapping_scale : controls depth of Offset Mapping\n"
 "r_shadow_glsl_offsetmapping_bias : should be negative half of scale\n"
 "r_shadow_glsl_offsetmapping : enables Offset Mapping bumpmap enhancement\n"
 "r_shadow_glsl_offsetmapping_scale : controls depth of Offset Mapping\n"
 "r_shadow_glsl_offsetmapping_bias : should be negative half of scale\n"
-"r_shadow_glsl_geforcefxlowquality : use lower quality lighting\n"
+"r_shadow_glsl_usehalffloat : use lower quality lighting\n"
 "r_shadow_glsl_surfacenormalize : makes bumpmapping slightly higher quality\n"
 "r_shadow_scissor : use scissor optimization\n"
 "r_shadow_shadow_polygonfactor : nudge shadow volumes closer/further\n"
 "r_shadow_glsl_surfacenormalize : makes bumpmapping slightly higher quality\n"
 "r_shadow_scissor : use scissor optimization\n"
 "r_shadow_shadow_polygonfactor : nudge shadow volumes closer/further\n"
@@ -668,7 +668,7 @@ void R_Shadow_Init(void)
        Cvar_RegisterVariable(&r_shadow_glsl_offsetmapping);
        Cvar_RegisterVariable(&r_shadow_glsl_offsetmapping_scale);
        Cvar_RegisterVariable(&r_shadow_glsl_offsetmapping_bias);
        Cvar_RegisterVariable(&r_shadow_glsl_offsetmapping);
        Cvar_RegisterVariable(&r_shadow_glsl_offsetmapping_scale);
        Cvar_RegisterVariable(&r_shadow_glsl_offsetmapping_bias);
-       Cvar_RegisterVariable(&r_shadow_glsl_geforcefxlowquality);
+       Cvar_RegisterVariable(&r_shadow_glsl_usehalffloat);
        Cvar_RegisterVariable(&r_shadow_glsl_surfacenormalize);
        Cvar_RegisterVariable(&gl_ext_stenciltwoside);
        if (gamemode == GAME_TENEBRAE)
        Cvar_RegisterVariable(&r_shadow_glsl_surfacenormalize);
        Cvar_RegisterVariable(&gl_ext_stenciltwoside);
        if (gamemode == GAME_TENEBRAE)
@@ -1224,7 +1224,7 @@ void R_Shadow_Stage_Lighting(int stenciltest)
                        r_shadow_lightpermutation |= SHADERPERMUTATION_OFFSETMAPPING;
                if (r_shadow_glsl_surfacenormalize.integer && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_SURFACENORMALIZE])
                        r_shadow_lightpermutation |= SHADERPERMUTATION_SURFACENORMALIZE;
                        r_shadow_lightpermutation |= SHADERPERMUTATION_OFFSETMAPPING;
                if (r_shadow_glsl_surfacenormalize.integer && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_SURFACENORMALIZE])
                        r_shadow_lightpermutation |= SHADERPERMUTATION_SURFACENORMALIZE;
-               if (r_shadow_glsl_geforcefxlowquality.integer && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_GEFORCEFX])
+               if (r_shadow_glsl_usehalffloat.integer && r_shadow_program_light[r_shadow_lightpermutation | SHADERPERMUTATION_GEFORCEFX])
                        r_shadow_lightpermutation |= SHADERPERMUTATION_GEFORCEFX;
                r_shadow_lightprog = r_shadow_program_light[r_shadow_lightpermutation];
                qglUseProgramObjectARB(r_shadow_lightprog);CHECKGLERROR
                        r_shadow_lightpermutation |= SHADERPERMUTATION_GEFORCEFX;
                r_shadow_lightprog = r_shadow_program_light[r_shadow_lightpermutation];
                qglUseProgramObjectARB(r_shadow_lightprog);CHECKGLERROR
@@ -1630,7 +1630,15 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles,
        {
                int passes = 0;
                if (r_shadow_glsl.integer && r_shadow_program_light[0])
        {
                int passes = 0;
                if (r_shadow_glsl.integer && r_shadow_program_light[0])
-                       passes++; // GLSL shader path (GFFX5200, Radeon 9500)
+               {
+                       // GLSL shader path (GFFX5200, Radeon 9500)
+                       // TODO: add direct pants/shirt rendering
+                       if (pantstexture && (r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorpants) > 0.001)
+                               R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, lightcolorpants, vec3_origin, vec3_origin, pantstexture, NULL, NULL, bumptexture, NULL);
+                       if (shirttexture && (r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorshirt) > 0.001)
+                               R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, lightcolorshirt, vec3_origin, vec3_origin, shirttexture, NULL, NULL, bumptexture, NULL);
+                       passes++;
+               }
                else if (gl_dot3arb && gl_texturecubemap && r_textureunits.integer >= 2 && gl_combine.integer && gl_stencil)
                {
                        // TODO: add direct pants/shirt rendering
                else if (gl_dot3arb && gl_texturecubemap && r_textureunits.integer >= 2 && gl_combine.integer && gl_stencil)
                {
                        // TODO: add direct pants/shirt rendering
@@ -1743,6 +1751,11 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles,
        else if (r_shadowstage == R_SHADOWSTAGE_LIGHT_GLSL)
        {
                // GLSL shader path (GFFX5200, Radeon 9500)
        else if (r_shadowstage == R_SHADOWSTAGE_LIGHT_GLSL)
        {
                // GLSL shader path (GFFX5200, Radeon 9500)
+               // TODO: add direct pants/shirt rendering
+               if (pantstexture && (r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorpants) > 0.001)
+                       R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, lightcolorpants, vec3_origin, vec3_origin, pantstexture, NULL, NULL, bumptexture, NULL);
+               if (shirttexture && (r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorshirt) > 0.001)
+                       R_Shadow_RenderLighting(firstvertex, numvertices, numtriangles, elements, vertex3f, svector3f, tvector3f, normal3f, texcoord2f, lightcolorshirt, vec3_origin, vec3_origin, shirttexture, NULL, NULL, bumptexture, NULL);
                R_Mesh_VertexPointer(vertex3f);
                R_Mesh_TexCoordPointer(0, 2, texcoord2f);
                R_Mesh_TexCoordPointer(1, 3, svector3f);
                R_Mesh_VertexPointer(vertex3f);
                R_Mesh_TexCoordPointer(0, 2, texcoord2f);
                R_Mesh_TexCoordPointer(1, 3, svector3f);
@@ -1760,23 +1773,6 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles,
                R_Mesh_Draw(firstvertex, numvertices, numtriangles, elements);
                c_rt_lightmeshes++;
                c_rt_lighttris += numtriangles;
                R_Mesh_Draw(firstvertex, numvertices, numtriangles, elements);
                c_rt_lightmeshes++;
                c_rt_lighttris += numtriangles;
-               // TODO: add direct pants/shirt rendering
-               if (pantstexture && (r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorpants) > 0.001)
-               {
-                       R_Mesh_TexBind(1, R_GetTexture(pantstexture));
-                       qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "LightColor"), lightcolorpants[0], lightcolorpants[1], lightcolorpants[2]);CHECKGLERROR
-                       R_Mesh_Draw(firstvertex, numvertices, numtriangles, elements);
-                       c_rt_lightmeshes++;
-                       c_rt_lighttris += numtriangles;
-               }
-               if (shirttexture && (r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * VectorLength2(lightcolorshirt) > 0.001)
-               {
-                       R_Mesh_TexBind(1, R_GetTexture(shirttexture));
-                       qglUniform3fARB(qglGetUniformLocationARB(r_shadow_lightprog, "LightColor"), lightcolorshirt[0], lightcolorshirt[1], lightcolorshirt[2]);CHECKGLERROR
-                       R_Mesh_Draw(firstvertex, numvertices, numtriangles, elements);
-                       c_rt_lightmeshes++;
-                       c_rt_lighttris += numtriangles;
-               }
                GL_LockArrays(0, 0);
        }
        else if (r_shadowstage == R_SHADOWSTAGE_LIGHT_DOT3)
                GL_LockArrays(0, 0);
        }
        else if (r_shadowstage == R_SHADOWSTAGE_LIGHT_DOT3)
@@ -3134,6 +3130,8 @@ rtexture_t *R_Shadow_Cubemap(const char *basename)
        numcubemaps++;
        strcpy(cubemaps[i].basename, basename);
        cubemaps[i].texture = R_Shadow_LoadCubemap(cubemaps[i].basename);
        numcubemaps++;
        strcpy(cubemaps[i].basename, basename);
        cubemaps[i].texture = R_Shadow_LoadCubemap(cubemaps[i].basename);
+       if (!cubemaps[i].texture)
+               cubemaps[i].texture = r_texture_whitecube;
        return cubemaps[i].texture;
 }
 
        return cubemaps[i].texture;
 }
 
@@ -3365,7 +3363,7 @@ void R_Shadow_LoadWorldLights(void)
 void R_Shadow_SaveWorldLights(void)
 {
        dlight_t *light;
 void R_Shadow_SaveWorldLights(void)
 {
        dlight_t *light;
-       int bufchars, bufmaxchars;
+       size_t bufchars, bufmaxchars;
        char *buf, *oldbuf;
        char name[MAX_QPATH];
        char line[1024];
        char *buf, *oldbuf;
        char name[MAX_QPATH];
        char line[1024];
@@ -3388,7 +3386,7 @@ void R_Shadow_SaveWorldLights(void)
                        sprintf(line, "%s%f %f %f %f %f %f %f %d \"%s\" %f %f %f %f\n", light->shadow ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style, light->cubemapname, light->corona, light->angles[0], light->angles[1], light->angles[2]);
                else
                        sprintf(line, "%s%f %f %f %f %f %f %f %d\n", light->shadow ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style);
                        sprintf(line, "%s%f %f %f %f %f %f %f %d \"%s\" %f %f %f %f\n", light->shadow ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style, light->cubemapname, light->corona, light->angles[0], light->angles[1], light->angles[2]);
                else
                        sprintf(line, "%s%f %f %f %f %f %f %f %d\n", light->shadow ? "" : "!", light->origin[0], light->origin[1], light->origin[2], light->radius, light->color[0], light->color[1], light->color[2], light->style);
-               if (bufchars + (int) strlen(line) > bufmaxchars)
+               if (bufchars + strlen(line) > bufmaxchars)
                {
                        bufmaxchars = bufchars + strlen(line) + 2048;
                        oldbuf = buf;
                {
                        bufmaxchars = bufchars + strlen(line) + 2048;
                        oldbuf = buf;
@@ -3407,7 +3405,7 @@ void R_Shadow_SaveWorldLights(void)
                }
        }
        if (bufchars)
                }
        }
        if (bufchars)
-               FS_WriteFile(name, buf, bufchars);
+               FS_WriteFile(name, buf, (fs_offset_t)bufchars);
        if (buf)
                Mem_Free(buf);
 }
        if (buf)
                Mem_Free(buf);
 }
@@ -3623,6 +3621,12 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
                        }
                        else if (!strcmp("style", key))
                                style = atoi(value);
                        }
                        else if (!strcmp("style", key))
                                style = atoi(value);
+                       else if (!strcmp("skin", key))
+                               skin = (int)atof(value);
+                       else if (!strcmp("pflags", key))
+                               pflags = (int)atof(value);
+                       else if (!strcmp("effects", key))
+                               effects = (int)atof(value);
                        else if (r_refdef.worldmodel->type == mod_brushq3)
                        {
                                if (!strcmp("scale", key))
                        else if (r_refdef.worldmodel->type == mod_brushq3)
                        {
                                if (!strcmp("scale", key))
@@ -3630,12 +3634,6 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
                                if (!strcmp("fade", key))
                                        fadescale = atof(value);
                        }
                                if (!strcmp("fade", key))
                                        fadescale = atof(value);
                        }
-                       else if (!strcmp("skin", key))
-                               skin = (int)atof(value);
-                       else if (!strcmp("pflags", key))
-                               pflags = (int)atof(value);
-                       else if (!strcmp("effects", key))
-                               effects = (int)atof(value);
                }
                if (!islight)
                        continue;
                }
                if (!islight)
                        continue;
@@ -3698,6 +3696,10 @@ void R_Shadow_SetCursorLocationForView(void)
                push = -push;
                VectorMA(trace.endpos, push, r_viewforward, endpos);
                VectorMA(endpos, r_editlights_cursorpushoff.value, trace.plane.normal, endpos);
                push = -push;
                VectorMA(trace.endpos, push, r_viewforward, endpos);
                VectorMA(endpos, r_editlights_cursorpushoff.value, trace.plane.normal, endpos);
+       } 
+       else 
+       {
+               VectorClear( endpos );
        }
        r_editlights_cursorlocation[0] = floor(endpos[0] / r_editlights_cursorgrid.value + 0.5f) * r_editlights_cursorgrid.value;
        r_editlights_cursorlocation[1] = floor(endpos[1] / r_editlights_cursorgrid.value + 0.5f) * r_editlights_cursorgrid.value;
        }
        r_editlights_cursorlocation[0] = floor(endpos[0] / r_editlights_cursorgrid.value + 0.5f) * r_editlights_cursorgrid.value;
        r_editlights_cursorlocation[1] = floor(endpos[1] / r_editlights_cursorgrid.value + 0.5f) * r_editlights_cursorgrid.value;