]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
fix interaction of blendfunc with rtlights
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 6 Sep 2011 17:02:34 +0000 (17:02 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 6 Sep 2011 17:02:34 +0000 (17:02 +0000)
basically, we exclude a number of CUSTOMBLEND blendfuncs from receiving rtlights
the rationale is not that doing this is always correct - it is not in some
cases (e.g. for crazy stuff like GL_ONE GL_SRC_COLOR). The rationale is that
the current behaviour for these is wrong too.

All surfaces that now receive rtlights, receive it correctly.

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11326 d7cf8633-e32d-0410-b094-e92efae38249

gl_rsurf.c
model_shared.c

index ed5534ae5abc6567b330527d5e6c28c2f3782a63..0a266c9c0577cfb4e2888820b991d9f71b81e4a7 100644 (file)
@@ -1494,8 +1494,52 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface
                                ;
                        // now figure out what to do with this particular range of surfaces
                        // VorteX: added MATERIALFLAG_NORTLIGHT
-                       if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WALL + MATERIALFLAG_NORTLIGHT)) != MATERIALFLAG_WALL)
+                       if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_NORTLIGHT)) != MATERIALFLAG_WALL)
                                continue;
+
+                       // divVerent:
+                       // rtlights basically add diffusetex * Color_Diffuse to the output
+                       // so intended outcome is originalcolor_out * (lightmapcolor + rtlightcolor)
+                       //
+                       // for MATERIALFLAG_ADD, this calculation is obviously right (linear map of input, output depending on src alpha)
+                       // for MATERIALFLAG_ALPHA, obviously too (linear map of input, output depending on src alpha)
+                       // for blendfuncs where the output is NOT linear in input, output, possibly depending on src alpha, this is WRONG!
+                       // furthermore, output MUST have GL_SRC_ALPHA or GL_ONE as blending factor, or the maths rtlights use are wrong
+                       //
+                       if (rsurface.texture->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND)
+                       {
+                               // source side MUST be using GL_SRC_ALPHA or GL_ONE
+                               // as nothing else is handled right by the rtlight pass
+                               if(rsurface.texture->currentlayers[0].blendfunc1 != GL_SRC_ALPHA)
+                               if(rsurface.texture->currentlayers[0].blendfunc1 != GL_ONE)
+                                       continue;
+
+                               // dest side MUST NOT depend on src color
+                               // or the assumptions how rtlights change src are wrong
+                               if(rsurface.texture->currentlayers[0].blendfunc2 == GL_SRC_COLOR)
+                                       continue;
+                               if(rsurface.texture->currentlayers[0].blendfunc2 == GL_ONE_MINUS_SRC_COLOR)
+                                       continue;
+
+                               // customblends that can get through this:
+                               // GL_SRC_ALPHA GL_ONE (cannot happen, handled by MATERIALFLAG_ADD)
+                               // GL_SRC_ALPHA GL_ZERO (stupid but handled correctly)
+                               // GL_SRC_ALPHA GL_SRC_ALPHA (stupid but handled correctly)
+                               // GL_SRC_ALPHA GL_DST_COLOR (stupid but handled correctly)
+                               // GL_SRC_ALPHA GL_DST_ALPHA (stupid but handled correctly)
+                               // GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA (stupid but handled correctly)
+                               // GL_SRC_ALPHA GL_ONE_MINUS_DST_COLOR (stupid but handled correctly)
+                               // GL_SRC_ALPHA GL_ONE_MINUS_DST_ALPHA (stupid but handled correctly)
+                               // GL_ONE GL_ONE (cannot happen, handled by MATERIALFLAG_ADD)
+                               // GL_ONE GL_ZERO (cannot happen, handled by default mode)
+                               // GL_ONE GL_SRC_ALPHA (inverse premultiplied alpha - and correct)
+                               // GL_ONE GL_DST_COLOR (stupid but handled correctly)
+                               // GL_ONE GL_DST_ALPHA (stupid but handled correctly)
+                               // GL_ONE GL_ONE_MINUS_SRC_ALPHA (premultiplied alpha - and correct)
+                               // GL_ONE GL_ONE_MINUS_DST_COLOR (stupid but handled correctly)
+                               // GL_ONE GL_ONE_MINUS_DST_ALPHA (stupid but handled correctly)
+                       }
+
                        if (r_waterstate.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA)))
                                continue;
                        if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
index dc6e798e366d542c970434d0f5664c8e564d0532..c4907d069621a0ac034ebdf8ef04fb88d1797b28 100644 (file)
@@ -1816,7 +1816,7 @@ void Mod_LoadQ3Shaders(void)
                                                                        else if (!strcasecmp(parameter[k+1], "GL_DST_COLOR"))
                                                                                layer->blendfunc[k] = GL_DST_COLOR;
                                                                        else if (!strcasecmp(parameter[k+1], "GL_DST_ALPHA"))
-                                                                               layer->blendfunc[k] = GL_ONE_MINUS_DST_ALPHA;
+                                                                               layer->blendfunc[k] = GL_DST_ALPHA;
                                                                        else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_SRC_COLOR"))
                                                                                layer->blendfunc[k] = GL_ONE_MINUS_SRC_COLOR;
                                                                        else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_SRC_ALPHA"))