diff --git a/src/gl/scene/gl_drawinfo.h b/src/gl/scene/gl_drawinfo.h index d7eb86ce..3da7cf02 100644 --- a/src/gl/scene/gl_drawinfo.h +++ b/src/gl/scene/gl_drawinfo.h @@ -52,6 +52,7 @@ enum Drawpasses GLPASS_DECALS, // Draws a decal GLPASS_DECALS_NOFOG,// Draws a decal without setting the fog (used for passes that need a fog layer) GLPASS_TRANSLUCENT, // Draws translucent objects + GLPASS_ALL // Everything at once, using shaders for dynamic lights }; //========================================================================== diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 2f44017c..e765a332 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -163,52 +163,49 @@ extern FDynLightData lightdata; bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub) { - if (gl_dynlight_shader && GLRenderer->mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT) + Plane p; + + lightdata.Clear(); + for(int i=0;i<2;i++) { - Plane p; - - lightdata.Clear(); - for(int i=0;i<2;i++) + FLightNode * node = sub->lighthead[i]; + while (node) { - FLightNode * node = sub->lighthead[i]; - while (node) + ADynamicLight * light = node->lightsource; + + if (light->flags2&MF2_DORMANT) { - ADynamicLight * light = node->lightsource; - - if (light->flags2&MF2_DORMANT) - { - node=node->nextLight; - continue; - } - iter_dlightf++; - - // we must do the side check here because gl_SetupLight needs the correct plane orientation - // which we don't have for Legacy-style 3D-floors - fixed_t planeh = plane.plane.ZatPoint(light->x, light->y); - if (gl_lights_checkside && ((planehz && ceiling) || (planeh>light->z && !ceiling))) - { - node=node->nextLight; - continue; - } - - p.Set(plane.plane); - gl_GetLight(p, light, Colormap.colormap, false, foggy, lightdata); - node = node->nextLight; + node=node->nextLight; + continue; } - } + iter_dlightf++; - int numlights[3]; + // we must do the side check here because gl_SetupLight needs the correct plane orientation + // which we don't have for Legacy-style 3D-floors + fixed_t planeh = plane.plane.ZatPoint(light->x, light->y); + if (gl_lights_checkside && ((planehz && ceiling) || (planeh>light->z && !ceiling))) + { + node=node->nextLight; + continue; + } - lightdata.Combine(numlights, gl.MaxLights()); - if (numlights[2] > 0) - { - draw_dlightf+=numlights[2]/2; - gl_RenderState.EnableLight(true); - gl_RenderState.SetLights(numlights, &lightdata.arrays[0][0]); - gl_RenderState.Apply(); - return true; + p.Set(plane.plane); + gl_GetLight(p, light, Colormap.colormap, false, false, lightdata); + node = node->nextLight; } } + + int numlights[3]; + + lightdata.Combine(numlights, gl.MaxLights()); + if (numlights[2] > 0) + { + draw_dlightf+=numlights[2]/2; + gl_RenderState.EnableLight(true); + gl_RenderState.SetLights(numlights, &lightdata.arrays[0][0]); + gl_RenderState.Apply(); + return true; + } if (lightsapplied) { gl_RenderState.EnableLight(false); @@ -254,7 +251,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) if (sub) { // This represents a single subsector - if (pass == GLPASS_PLAIN) lightsapplied = SetupSubsectorLights(lightsapplied, sub); + if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub); DrawSubsector(sub); } else @@ -269,7 +266,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) // This is just a quick hack to make translucent 3D floors and portals work. if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) { - if (pass == GLPASS_PLAIN) lightsapplied = SetupSubsectorLights(lightsapplied, sub); + if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub); gl.DrawArrays(GL_TRIANGLE_FAN, index, sub->numlines); flatvertices += sub->numlines; flatprimitives++; @@ -286,7 +283,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) subsector_t * sub = sector->subsectors[i]; if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans) { - if (pass == GLPASS_PLAIN) lightsapplied = SetupSubsectorLights(lightsapplied, sub); + if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub); DrawSubsector(sub); } } @@ -301,7 +298,7 @@ void GLFlat::DrawSubsectors(int pass, bool istrans) while (node) { - if (pass == GLPASS_PLAIN) lightsapplied = SetupSubsectorLights(lightsapplied, node->sub); + if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, node->sub); DrawSubsector(node->sub); node = node->next; } @@ -338,11 +335,10 @@ void GLFlat::Draw(int pass) break; case GLPASS_PLAIN: // Single-pass rendering - + case GLPASS_ALL: case GLPASS_BASE_MASKED: gl_SetColor(lightlevel, rel, &Colormap,1.0f); - if (!foggy || pass == GLPASS_PLAIN) - gl_SetFog(lightlevel, rel, &Colormap, false); + if (!foggy || pass != GLPASS_BASE_MASKED) gl_SetFog(lightlevel, rel, &Colormap, false); // fall through case GLPASS_TEXTURE: gltexture->Bind(Colormap.colormap); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 0d0277e2..e8b712a0 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -344,15 +344,30 @@ void FGLRenderer::RenderScene(int recursion) gl.Disable(GL_POLYGON_OFFSET_FILL); // just in case + int pass; + + if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && gl_dynlight_shader) + { + pass = GLPASS_ALL; + } + else if (gl_texture) + { + pass = GLPASS_PLAIN; + } + else + { + pass = GLPASS_BASE; + } + gl_RenderState.EnableTexture(gl_texture); gl_RenderState.EnableBrightmap(true); gl_drawinfo->drawlists[GLDL_PLAIN].Sort(); - gl_drawinfo->drawlists[GLDL_PLAIN].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE); + gl_drawinfo->drawlists[GLDL_PLAIN].Draw(pass); gl_RenderState.EnableBrightmap(false); gl_drawinfo->drawlists[GLDL_FOG].Sort(); - gl_drawinfo->drawlists[GLDL_FOG].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE); + gl_drawinfo->drawlists[GLDL_FOG].Draw(pass); gl_drawinfo->drawlists[GLDL_LIGHTFOG].Sort(); - gl_drawinfo->drawlists[GLDL_LIGHTFOG].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE); + gl_drawinfo->drawlists[GLDL_LIGHTFOG].Draw(pass); gl.Enable(GL_ALPHA_TEST); @@ -363,18 +378,19 @@ void FGLRenderer::RenderScene(int recursion) gl_RenderState.EnableTexture(true); gl_RenderState.SetTextureMode(TM_MASK); } + if (pass == GLPASS_BASE) pass = GLPASS_BASE_MASKED; gl.AlphaFunc(GL_GEQUAL,gl_mask_threshold); gl_RenderState.EnableBrightmap(true); gl_drawinfo->drawlists[GLDL_MASKED].Sort(); - gl_drawinfo->drawlists[GLDL_MASKED].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE_MASKED); + gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass); gl_RenderState.EnableBrightmap(false); gl_drawinfo->drawlists[GLDL_FOGMASKED].Sort(); - gl_drawinfo->drawlists[GLDL_FOGMASKED].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE_MASKED); + gl_drawinfo->drawlists[GLDL_FOGMASKED].Draw(pass); gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Sort(); - gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Draw(gl_texture? GLPASS_PLAIN : GLPASS_BASE_MASKED); + gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Draw(pass); // And now the multipass stuff - if (!gl_dynlight_shader) + if (!gl_dynlight_shader && gl_lights) { // First pass: empty background with sector light only @@ -399,7 +415,7 @@ void FGLRenderer::RenderScene(int recursion) // second pass: draw lights (on fogged surfaces they are added to the textures!) gl.DepthMask(false); - if (gl_lights && mLightCount && !gl_fixedcolormap) + if (mLightCount && !gl_fixedcolormap) { if (gl_SetupLightTexture()) { diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index be192372..bed1cb12 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -97,11 +97,12 @@ void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend //========================================================================== void GLSprite::Draw(int pass) { + if (pass!=GLPASS_PLAIN && pass != GLPASS_ALL && pass!=GLPASS_TRANSLUCENT) return; + + bool additivefog = false; int rel = extralight*gl_weaponlight; - if (pass!=GLPASS_PLAIN && pass!=GLPASS_TRANSLUCENT) return; - if (pass==GLPASS_TRANSLUCENT) { // The translucent pass requires special setup for the various modes. diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index 1670162f..75f5cf29 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -196,7 +196,7 @@ void GLWall::SetupLights() } if (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4) { - gl_GetLight(p, node->lightsource, Colormap.colormap, true, !!(flags&GLWF_FOGGY), lightdata); + gl_GetLight(p, node->lightsource, Colormap.colormap, true, false, lightdata); } } } @@ -296,6 +296,7 @@ void GLWall::RenderFogBoundary() { if (gl_fogmode && gl_fixedcolormap == 0) { + // with shaders this can be done properly if (gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_fog_shader)) { int rel = rellight + (extralight * gl_weaponlight); @@ -308,6 +309,8 @@ void GLWall::RenderFogBoundary() } else { + // otherwise some approximation is needed. This won't look as good + // as the shader version but it's an acceptable compromise. float fogdensity=gl_GetFogDensity(lightlevel, Colormap.FadeColor); float xcamera=TO_GL(viewx); @@ -351,6 +354,7 @@ void GLWall::RenderMirrorSurface() { if (GLRenderer->mirrortexture == NULL) return; + // For the sphere map effect we need a normal of the mirror surface, Vector v(glseg.y2-glseg.y1, 0 ,-glseg.x2+glseg.x1); v.Normalize(); glNormal3fv(&v[0]); @@ -474,36 +478,37 @@ void GLWall::Draw(int pass) switch (pass) { + case GLPASS_ALL: // Single-pass rendering + SetupLights(); + // fall through + case GLPASS_PLAIN: // Single-pass rendering - - if (gl_dynlight_shader && GLRenderer->mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT) - { - SetupLights(); - } - case GLPASS_BASE: // Base pass for non-masked polygons (all opaque geometry) case GLPASS_BASE_MASKED: // Base pass for masked polygons (2sided mid-textures and transparent 3D floors) - rel = rellight + (extralight * gl_weaponlight); gl_SetColor(lightlevel, rel, &Colormap,1.0f); - if (!(flags&GLWF_FOGGY) || pass == GLPASS_PLAIN) + if (!(flags&GLWF_FOGGY) || pass == GLPASS_PLAIN || pass == GLPASS_ALL) { if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false); else gl_SetFog(255, 0, NULL, false); } gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW)); - // fall through - case GLPASS_TEXTURE: // modulated texture + if (pass != GLPASS_BASE) { gltexture->Bind(Colormap.colormap, flags, 0); } - RenderWall((pass!=GLPASS_BASE) + 2*(pass!=GLPASS_TEXTURE), NULL); + RenderWall(pass == GLPASS_BASE? 2:3, NULL); gl_RenderState.EnableGlow(false); gl_RenderState.EnableLight(false); break; + case GLPASS_TEXTURE: // modulated texture + gltexture->Bind(Colormap.colormap, flags, 0); + RenderWall(1, NULL); + break; + case GLPASS_LIGHT: case GLPASS_LIGHT_ADDITIVE: // black fog is diminishing light and should affect lights less than the rest!