]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - r_shadow.c
Implement GPU-side corona fading
[xonotic/darkplaces.git] / r_shadow.c
index 79ab59f07d9c57d2c36ac987781f4a2fcaa3c509..ff8792db3f8df1a5ed9047bef59715919eaf5a86 100644 (file)
@@ -3941,6 +3941,7 @@ static void R_Shadow_PrepareLight(rtlight_t *rtlight)
        rtlight->cached_numshadowentities              = 0;
        rtlight->cached_numshadowentities_noselfshadow = 0;
        rtlight->cached_numsurfaces                    = 0;
+       rtlight->occlusion_buf                         = 0;
        rtlight->cached_lightentities                  = NULL;
        rtlight->cached_lightentities_noselfshadow     = NULL;
        rtlight->cached_shadowentities                 = NULL;
@@ -5147,7 +5148,9 @@ static float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
 static void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
 {
        vec3_t color;
+       unsigned int occlude = 0;
        GLint allpixels = 0, visiblepixels = 0;
+
        // now we have to check the query result
        if (rtlight->corona_queryindex_visiblepixels)
        {
@@ -5160,29 +5163,44 @@ static void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
                case RENDERPATH_GLES2:
 #if defined(GL_SAMPLES_PASSED_ARB) && !defined(USE_GLES2)
                        CHECKGLERROR
-                       qglGetQueryObjectivARB(rtlight->corona_queryindex_visiblepixels, GL_QUERY_RESULT_ARB, &visiblepixels);
-                       qglGetQueryObjectivARB(rtlight->corona_queryindex_allpixels, GL_QUERY_RESULT_ARB, &allpixels);
+                       // See if we can use the GPU-side method to prevent implicit sync
+                       if (vid.support.arb_query_buffer_object) {
+#define BUFFER_OFFSET(i)    ((void*)NULL + (i))
+                               qglGenBuffersARB(1, &rtlight->occlusion_buf);
+                               qglBindBufferARB(GL_QUERY_BUFFER_ARB, rtlight->occlusion_buf);
+                               qglBufferDataARB(GL_QUERY_BUFFER_ARB, 8, NULL, GL_DYNAMIC_COPY);
+                               qglGetQueryObjectivARB(rtlight->corona_queryindex_visiblepixels, GL_QUERY_RESULT_ARB, BUFFER_OFFSET(0));
+                               qglGetQueryObjectivARB(rtlight->corona_queryindex_allpixels, GL_QUERY_RESULT_ARB, BUFFER_OFFSET(4));
+                               qglBindBufferBase(GL_UNIFORM_BUFFER, 0, rtlight->occlusion_buf);
+                               occlude = MATERIALFLAG_OCCLUDE;
+                       } else {
+                               qglGetQueryObjectivARB(rtlight->corona_queryindex_visiblepixels, GL_QUERY_RESULT_ARB, &visiblepixels);
+                               qglGetQueryObjectivARB(rtlight->corona_queryindex_allpixels, GL_QUERY_RESULT_ARB, &allpixels); 
+                               if (visiblepixels < 1 || allpixels < 1)
+                                       return;
+                               rtlight->corona_visibility *= bound(0, (float)visiblepixels / (float)allpixels, 1);
+                       }
+                       cscale *= rtlight->corona_visibility;
                        CHECKGLERROR
-#endif
                        break;
+#else
+                       return;
+#endif
                case RENDERPATH_D3D9:
                        Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-                       break;
+                       return;
                case RENDERPATH_D3D10:
                        Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-                       break;
+                       return;
                case RENDERPATH_D3D11:
                        Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-                       break;
+                       return;
                case RENDERPATH_SOFT:
                        //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
-                       break;
-               }
-               //Con_Printf("%i of %i pixels\n", (int)visiblepixels, (int)allpixels);
-               if (visiblepixels < 1 || allpixels < 1)
                        return;
-               rtlight->corona_visibility *= bound(0, (float)visiblepixels / (float)allpixels, 1);
-               cscale *= rtlight->corona_visibility;
+               default:
+                       return;
+               }
        }
        else
        {
@@ -5202,10 +5220,13 @@ static void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale)
                }
                R_CalcSprite_Vertex3f(vertex3f, rtlight->shadoworigin, r_refdef.view.right, r_refdef.view.up, scale, -scale, -scale, scale);
                RSurf_ActiveCustomEntity(&identitymatrix, &identitymatrix, RENDER_NODEPTHTEST, 0, color[0], color[1], color[2], 1, 4, vertex3f, spritetexcoord2f, NULL, NULL, NULL, NULL, 2, polygonelement3i, polygonelement3s, false, false);
-               R_DrawCustomSurface(r_shadow_lightcorona, &identitymatrix, MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_NOCULLFACE | MATERIALFLAG_NODEPTHTEST, 0, 4, 0, 2, false, false);
+               R_DrawCustomSurface(r_shadow_lightcorona, &identitymatrix, MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_NOCULLFACE | MATERIALFLAG_NODEPTHTEST | occlude, 0, 4, 0, 2, false, false);
                if(negated)
                        GL_BlendEquationSubtract(false);
        }
+       if (rtlight->occlusion_buf) {
+               qglDeleteBuffersARB(1, &rtlight->occlusion_buf);
+       }
 }
 
 void R_Shadow_DrawCoronas(void)