Commit: ff7220349d32e747c7559809d68de7d835c0c1cd
Author: Antony Riakiotakis
Date:   Tue Feb 17 18:08:28 2015 +0100
Branches: master
https://developer.blender.org/rBff7220349d32e747c7559809d68de7d835c0c1cd

Compositing works with X-Ray.

Basically, before drawing X-Rays, we now bind a second depth buffer.
After drawing XRays, we do an extra resolve pass where we overwrite the
non-XRay depth buffer in pixels where the depth is not maximum (which
means background pixel, since depth is cleared before drawing X-Ray
objects).

This ensures both scene and X-Rays keep their depth values and are ready
for compositing. Well, the odd effect due to depth discontinuities can be
expected, and X-Rays are a bit more expensive (extra buffer + resolve pass)
but at least X-Rays won't invalidate depth values anymore. Whee!

===================================================================

M       SConstruct
M       source/blender/editors/space_view3d/view3d_draw.c
M       source/blender/gpu/CMakeLists.txt
M       source/blender/gpu/GPU_compositing.h
M       source/blender/gpu/intern/gpu_compositing.c
M       source/blender/gpu/intern/gpu_extensions.c
A       source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl

===================================================================

diff --git a/SConstruct b/SConstruct
index 225b532..29e22cb 100644
--- a/SConstruct
+++ b/SConstruct
@@ -765,6 +765,7 @@ if B.targets != ['cudakernels']:
     data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl")
     data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl")
     data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_lib.glsl")
+    
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl")
     data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_vert.glsl")
     data_to_c_simple("intern/opencolorio/gpu_shader_display_transform.glsl")
 
diff --git a/source/blender/editors/space_view3d/view3d_draw.c 
b/source/blender/editors/space_view3d/view3d_draw.c
index f552d5c..b2aef64 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2666,7 +2666,7 @@ static void view3d_draw_objects(
         const bContext *C,
         Scene *scene, View3D *v3d, ARegion *ar,
         const char **grid_unit,
-        const bool do_bgpic, const bool draw_offscreen)
+        const bool do_bgpic, const bool draw_offscreen, bool do_compositing)
 {
        RegionView3D *rv3d = ar->regiondata;
        Base *base;
@@ -2675,6 +2675,7 @@ static void view3d_draw_objects(
        const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp 
!= RV3D_ORTHO);
        /* only draw grids after in solid modes, else it hovers over mesh wires 
*/
        const bool draw_grids_after = draw_grids && draw_floor && 
(v3d->drawtype > OB_WIRE);
+       bool do_composite_xray = false;
        bool xrayclear = true;
 
        if (!draw_offscreen) {
@@ -2814,9 +2815,20 @@ static void view3d_draw_objects(
 
        /* transp and X-ray afterdraw stuff */
        if (v3d->afterdraw_transp.first)     view3d_draw_transp(scene, ar, v3d);
+
+       /* always do that here to cleanup depth buffers if none needed */
+       if (do_compositing) {
+               do_composite_xray = v3d->zbuf && (v3d->afterdraw_xray.first || 
v3d->afterdraw_xraytransp.first);
+               GPU_fx_compositor_setup_XRay_pass(rv3d->compositor, 
do_composite_xray);
+       }
+
        if (v3d->afterdraw_xray.first)       view3d_draw_xray(scene, ar, v3d, 
&xrayclear);
        if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, 
v3d, xrayclear);
 
+       if (do_compositing && do_composite_xray) {
+               GPU_fx_compositor_XRay_resolve(rv3d->compositor);
+       }
+
        if (!draw_offscreen) {
                ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
        }
@@ -3117,11 +3129,11 @@ void ED_view3d_draw_offscreen(
        }
        else {
                glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-               glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);             
+               glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        }
 
        /* main drawing call */
-       view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true);
+       view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, 
do_compositing);
 
        /* post process */
        if (do_compositing) {
@@ -3551,7 +3563,7 @@ static void view3d_main_area_draw_objects(const bContext 
*C, Scene *scene, View3
        }
 
        /* main drawing call */
-       view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false);
+       view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, 
do_compositing);
 
        /* post process */
        if (do_compositing) {
diff --git a/source/blender/gpu/CMakeLists.txt 
b/source/blender/gpu/CMakeLists.txt
index 7e32105..12b7f86 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -69,6 +69,7 @@ set(SRC
        shaders/gpu_shader_vertex.glsl
        shaders/gpu_shader_vsm_store_frag.glsl
        shaders/gpu_shader_vsm_store_vert.glsl
+       shaders/gpu_shader_fx_depth_resolve.glsl
 
        GPU_buffers.h
        GPU_draw.h
@@ -96,6 +97,7 @@ data_to_c_simple(shaders/gpu_shader_fx_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_fx_ssao_frag.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_fx_dof_frag.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_fx_dof_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fx_depth_resolve.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_fx_lib.glsl SRC)
 
 if(WITH_GAMEENGINE)
diff --git a/source/blender/gpu/GPU_compositing.h 
b/source/blender/gpu/GPU_compositing.h
index 796341d..93f1bc6 100644
--- a/source/blender/gpu/GPU_compositing.h
+++ b/source/blender/gpu/GPU_compositing.h
@@ -60,10 +60,12 @@ typedef enum GPUFXShaderEffect {
        GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE = 4,
        GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR = 5,
        GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE = 6,
+
+       GPU_SHADER_FX_DEPTH_RESOLVE = 7,
 } GPUFXShaderEffect;
 
 /* keep in synch with enum above! */
-#define MAX_FX_SHADERS 11
+#define MAX_FX_SHADERS 8
 
 /* generate a new FX compositor */
 GPUFX *GPU_fx_compositor_create(void);
@@ -79,6 +81,12 @@ bool GPU_fx_compositor_initialize_passes(
 /* do compositing on the fx passes that have been initialized */
 bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, 
struct Scene *scene, struct GPUOffScreen *ofs);
 
+/* bind new depth buffer for XRay pass */
+void GPU_fx_compositor_setup_XRay_pass(GPUFX *fx, bool do_xray);
+
+/* resolve a final depth buffer by compositing the XRay and normal depth 
buffers */
+void GPU_fx_compositor_XRay_resolve(GPUFX *fx);
+
 void GPU_fx_compositor_init_dof_settings(struct GPUDOFSettings *dof);
 void GPU_fx_compositor_init_ssao_settings(struct GPUSSAOSettings *ssao);
 #ifdef __cplusplus
diff --git a/source/blender/gpu/intern/gpu_compositing.c 
b/source/blender/gpu/intern/gpu_compositing.c
index cf28807..32d8050 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -89,6 +89,7 @@ struct GPUFX {
 
        /* texture bound to the depth attachment of the gbuffer */
        GPUTexture *depth_buffer;
+       GPUTexture *depth_buffer_xray;
 
        /* texture used for jittering for various effects */
        GPUTexture *jitter_buffer;
@@ -213,6 +214,12 @@ static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
                fx->depth_buffer = NULL;
        }
 
+       if (fx->depth_buffer_xray) {
+               GPU_framebuffer_texture_detach(fx->depth_buffer_xray);
+               GPU_texture_free(fx->depth_buffer_xray);
+               fx->depth_buffer_xray = NULL;
+       }
+
        cleanup_fx_dof_buffers(fx);
 
        if (fx->ssao_concentric_samples_tex) {
@@ -452,6 +459,88 @@ static void gpu_fx_bind_render_target(int *passes_left, 
GPUFX *fx, struct GPUOff
        }
 }
 
+void GPU_fx_compositor_setup_XRay_pass(GPUFX *fx, bool do_xray)
+{
+       char err_out[256];
+
+       if (do_xray) {
+               if (!fx->depth_buffer_xray && !(fx->depth_buffer_xray = 
GPU_texture_create_depth(fx->gbuffer_dim[0], fx->gbuffer_dim[1], err_out))) {
+                       printf("%.256s\n", err_out);
+                       cleanup_fx_gl_data(fx, true);
+                       return;
+               }
+       }
+       else {
+               if (fx->depth_buffer_xray) {
+                       GPU_framebuffer_texture_detach(fx->depth_buffer_xray);
+                       GPU_texture_free(fx->depth_buffer_xray);
+                       fx->depth_buffer_xray = NULL;
+               }
+               return;
+       }
+
+       GPU_framebuffer_texture_detach(fx->depth_buffer);
+
+       /* first depth buffer, because system assumes read/write buffers */
+       if(!GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer_xray, 
0, err_out))
+               printf("%.256s\n", err_out);
+}
+
+
+void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
+{
+       GPUShader *depth_resolve_shader;
+       GPU_framebuffer_texture_detach(fx->depth_buffer_xray);
+
+       /* attach regular framebuffer */
+       GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, NULL);
+
+       /* full screen quad where we will always write to depth buffer */
+       glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_SCISSOR_BIT);
+       glDepthFunc(GL_ALWAYS);
+       /* disable scissor from sculpt if any */
+       glDisable(GL_SCISSOR_TEST);
+       /* disable writing to color buffer, it's depth only pass */
+       glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+       /* set up quad buffer */
+       glVertexPointer(2, GL_FLOAT, 0, fullscreencos);
+       glTexCoordPointer(2, GL_FLOAT, 0, fullscreenuvs);
+       glEnableClientState(GL_VERTEX_ARRAY);
+       glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+       depth_resolve_shader = 
GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_RESOLVE, false);
+
+       if (depth_resolve_shader) {
+               int depth_uniform;
+
+               depth_uniform = GPU_shader_get_uniform(depth_resolve_shader, 
"depthbuffer");
+
+               GPU_shader_bind(depth_resolve_shader);
+
+               GPU_texture_bind(fx->depth_buffer_xray, 0);
+               GPU_depth_texture_mode(fx->depth_buffer_xray, false, true);
+               GPU_shader_uniform_texture(depth_resolve_shader, depth_uniform, 
fx->depth_buffer_xray);
+
+               /* draw */
+               glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+               /* disable bindings */
+               GPU_depth_texture_mode(fx->depth_buffer_xray, true, false);
+               GPU_texture_unbind(fx->depth_buffer_xray);
+
+               GPU_shader_unbind();
+       }
+
+       glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+       glDisableClientState(GL_VERTEX_ARRAY);
+       glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+       glPopAttrib();
+}
+
+
 bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, 
struct Scene *scene, struct GPUOffScreen *ofs)
 {
        GPUTexture *src, *target;
diff --git a/source/blender/gpu/intern/gpu_extensions.c 
b/source/blender/gpu/intern/gpu_extensions.c
index 4d1a977..1d08187 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -83,6 +83,7 @@ extern char datatoc_gpu_shader_fx_vert_glsl[];
 extern char datatoc_gpu_shader_fx_ssao_frag_glsl[];
 extern char datatoc_gpu_shader_fx_dof_frag_glsl[];
 extern char datatoc_gpu_shader_fx_dof_vert_glsl[];
+extern char datatoc_gpu_shader_fx_depth_resolve_glsl[];
 extern char datatoc_gpu_shader_fx_lib_glsl[];
 
 typedef struct GPUShaders {
@@ -1776,6 +1777,9 @@ GPUShader *GPU_shader_get_builtin_fx_shader(int effects, 
bool persp)
                                strcat(defines, "#define FIFTH_PASS\n");
                                GG.shaders.fx_shaders[offset] = 
GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, 
datatoc_gpu_shader_fx_dof_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
                                break;
+
+                       case GPU_SHADER_FX_DEPTH_RESOLVE:
+                               GG.shaders.fx_shaders[offset] = 
GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, 
datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, defines);
                }
        }
 
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl 
b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
new file mode 100644
index 0000000..e04cd7d
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_dep

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to