Commit: 7a3e06b9f7847fd34021f90ad1d2119021b63659
Author: Campbell Barton
Date:   Sun Mar 5 19:12:24 2017 +1100
Branches: temp-select-pick
https://developer.blender.org/rB7a3e06b9f7847fd34021f90ad1d2119021b63659

Added back multi-pass occlusion queries

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

M       source/blender/editors/space_view3d/view3d_view.c
M       source/blender/editors/transform/transform_manipulator.c
M       source/blender/gpu/GPU_select.h
M       source/blender/gpu/intern/gpu_select.c

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

diff --git a/source/blender/editors/space_view3d/view3d_view.c 
b/source/blender/editors/space_view3d/view3d_view.c
index ccf9f4d0d4..e23d01e679 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1206,13 +1206,13 @@ short view3d_opengl_select(
                ED_view3d_clipping_set(vc->rv3d);
        
        if (select_mode == VIEW3D_SELECT_DEPTH_SORT_NEAREST) {
-               GPU_select_begin(buffer, bufsize, &rect, 
GPU_SELECT_DEPTH_SORT_NEAREST);
+               GPU_select_begin(buffer, bufsize, &rect, 
GPU_SELECT_DEPTH_SORT_NEAREST, 0);
        }
        else if (select_mode == VIEW3D_SELECT_DEPTH_SORT_ALL) {
-               GPU_select_begin(buffer, bufsize, &rect, 
GPU_SELECT_DEPTH_SORT_ALL);
+               GPU_select_begin(buffer, bufsize, &rect, 
GPU_SELECT_DEPTH_SORT_ALL, 0);
        }
        else {
-               GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_ALL);
+               GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_ALL, 0);
        }
 
        view3d_select_loop(vc, scene, v3d, ar, use_obedit_skip);
diff --git a/source/blender/editors/transform/transform_manipulator.c 
b/source/blender/editors/transform/transform_manipulator.c
index a1dd964ff1..1567cafeb0 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -1728,6 +1728,7 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion 
*ar, const int mval[2], fl
        GLuint buffer[64];      // max 4 items per select, so large enuf
        short hits;
        const bool is_picksel = true;
+       const bool do_passes = GPU_select_query_check_active();
 
        /* XXX check a bit later on this... (ton) */
        extern void view3d_winmatrix_set(ARegion *ar, View3D *v3d, rctf *rect);
@@ -1747,7 +1748,10 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion 
*ar, const int mval[2], fl
        view3d_winmatrix_set(ar, v3d, &rect);
        mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
 
-       GPU_select_begin(buffer, 64, &selrect, GPU_SELECT_DEPTH_SORT_NEAREST);
+       if (do_passes)
+               GPU_select_begin(buffer, 64, &selrect, 
GPU_SELECT_NEAREST_FIRST_PASS, 0);
+       else
+               GPU_select_begin(buffer, 64, &selrect, GPU_SELECT_ALL, 0);
 
        /* do the drawing */
        if (v3d->twtype & V3D_MANIP_ROTATE) {
@@ -1761,6 +1765,22 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion 
*ar, const int mval[2], fl
 
        hits = GPU_select_end();
 
+       if (do_passes) {
+               GPU_select_begin(buffer, 64, &selrect, 
GPU_SELECT_NEAREST_SECOND_PASS, hits);
+
+               /* do the drawing */
+               if (v3d->twtype & V3D_MANIP_ROTATE) {
+                       if (G.debug_value == 3) 
draw_manipulator_rotate_cyl(v3d, rv3d, MAN_ROT_C & rv3d->twdrawflag, 
v3d->twtype, MAN_RGB, false, is_picksel);
+                       else draw_manipulator_rotate(v3d, rv3d, MAN_ROT_C & 
rv3d->twdrawflag, v3d->twtype, false, is_picksel);
+               }
+               if (v3d->twtype & V3D_MANIP_SCALE)
+                       draw_manipulator_scale(v3d, rv3d, MAN_SCALE_C & 
rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
+               if (v3d->twtype & V3D_MANIP_TRANSLATE)
+                       draw_manipulator_translate(v3d, rv3d, MAN_TRANS_C & 
rv3d->twdrawflag, v3d->twtype, MAN_RGB, false, is_picksel);
+
+               GPU_select_end();
+       }
+
        view3d_winmatrix_set(ar, v3d, NULL);
        mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
 
diff --git a/source/blender/gpu/GPU_select.h b/source/blender/gpu/GPU_select.h
index 343484775f..92e870d406 100644
--- a/source/blender/gpu/GPU_select.h
+++ b/source/blender/gpu/GPU_select.h
@@ -37,11 +37,13 @@ struct rctf;
 /* flags for mode of operation */
 enum {
        GPU_SELECT_ALL                      = 1,
-       GPU_SELECT_DEPTH_SORT_ALL           = 2,
-       GPU_SELECT_DEPTH_SORT_NEAREST       = 3,
+       GPU_SELECT_NEAREST_FIRST_PASS       = 2,
+       GPU_SELECT_NEAREST_SECOND_PASS      = 3,
+       GPU_SELECT_DEPTH_SORT_ALL           = 4,
+       GPU_SELECT_DEPTH_SORT_NEAREST       = 5,
 };
 
-void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const struct 
rctf *input, char mode);
+void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const struct 
rctf *input, char mode, int oldhits);
 bool GPU_select_load_id(unsigned int id);
 unsigned int GPU_select_end(void);
 bool GPU_select_query_check_active(void);
diff --git a/source/blender/gpu/intern/gpu_select.c 
b/source/blender/gpu/intern/gpu_select.c
index 1b0c410867..9bcbb6f635 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -52,6 +52,8 @@
 /* Alloc number for depths */
 #define ALLOC_DEPTHS 200
 
+#define SELECT_ID_NONE ((unsigned int)0xffffffff)
+
 typedef struct DepthID {
        unsigned int id;
        float depth;
@@ -142,7 +144,7 @@ static GPUQueryState g_query_state = {0};
 /**
  * initialize and provide buffer for results
  */
-void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const rctf 
*input, char mode)
+void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const rctf 
*input, char mode, int oldhits)
 {
        g_query_state.select_is_active = true;
        g_query_state.query_issued = false;
@@ -153,7 +155,7 @@ void GPU_select_begin(unsigned int *buffer, unsigned int 
bufsize, const rctf *in
        g_query_state.buffer = buffer;
        g_query_state.mode = mode;
        g_query_state.index = 0;
-       g_query_state.oldhits = 0;
+       g_query_state.oldhits = oldhits;
 
        if (!g_query_state.use_gpu_select) {
                glSelectBuffer(bufsize, (GLuint *)buffer);
@@ -237,8 +239,21 @@ void GPU_select_begin(unsigned int *buffer, unsigned int 
bufsize, const rctf *in
 
                /* occlusion queries operates on fragments that pass tests and 
since we are interested on all
                 * objects in the view frustum independently of their order, we 
need to disable the depth test */
-               glDisable(GL_DEPTH_TEST);
-               glDepthMask(GL_FALSE);
+               if (mode == GPU_SELECT_ALL) {
+                       glDisable(GL_DEPTH_TEST);
+                       glDepthMask(GL_FALSE);
+               }
+               else if (mode == GPU_SELECT_NEAREST_FIRST_PASS) {
+                       glClear(GL_DEPTH_BUFFER_BIT);
+                       glEnable(GL_DEPTH_TEST);
+                       glDepthMask(GL_TRUE);
+                       glDepthFunc(GL_LEQUAL);
+               }
+               else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
+                       glEnable(GL_DEPTH_TEST);
+                       glDepthMask(GL_FALSE);
+                       glDepthFunc(GL_EQUAL);
+               }
        }
 }
 
@@ -265,9 +280,9 @@ bool GPU_select_load_id(unsigned int id)
                        glReadPixels(UNPACK4(qsd->clip_readpixels), 
GL_DEPTH_COMPONENT, GL_FLOAT, qsd->rect_depth_test);
                        /* perform initial memcmp since most cases the array 
remains unchanged  */
                        if (memcmp(qsd->rect_depth, qsd->rect_depth_test, 
rect_len * sizeof(float)) != 0) {
+                               const unsigned int prev_id = qsd->prev_id;
                                if (g_query_state.mode == 
GPU_SELECT_DEPTH_SORT_ALL) {
                                        /* find the best depth for this pass 
and store in 'all.hits' */
-                                       const unsigned int prev_id = 
qsd->prev_id;
                                        const float *prev = qsd->rect_depth;
                                        const float *curr = 
qsd->rect_depth_test;
                                        float depth_best = FLT_MAX;
@@ -289,13 +304,14 @@ bool GPU_select_load_id(unsigned int id)
                                }
                                else {
                                        /* keep track each pixels ID in 
'nearest.rect_id' */
-                                       const unsigned int prev_id = 
qsd->prev_id;
-                                       const float *prev = qsd->rect_depth;
-                                       const float *curr = 
qsd->rect_depth_test;
-                                       unsigned int *id_ptr = 
qsd->nearest.rect_id;
-                                       for (unsigned int i = 0; i < rect_len; 
i++, curr++, prev++, id_ptr++) {
-                                               if (*curr != *prev) {
-                                                       *id_ptr = prev_id;
+                                       if (prev_id != SELECT_ID_NONE) {
+                                               const float *prev = 
qsd->rect_depth;
+                                               const float *curr = 
qsd->rect_depth_test;
+                                               unsigned int *id_ptr = 
qsd->nearest.rect_id;
+                                               for (unsigned int i = 0; i < 
rect_len; i++, curr++, prev++, id_ptr++) {
+                                                       if (*curr != *prev) {
+                                                               *id_ptr = 
prev_id;
+                                                       }
                                                }
                                        }
                                }
@@ -321,6 +337,16 @@ bool GPU_select_load_id(unsigned int id)
                g_query_state.id[g_query_state.active_query] = id;
                g_query_state.active_query++;
                g_query_state.query_issued = true;
+
+               if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS && 
g_query_state.index < g_query_state.oldhits) {
+                       if (g_query_state.buffer[g_query_state.index * 4 + 3] 
== id) {
+                               g_query_state.index++;
+                               return true;
+                       }
+                       else {
+                               return false;
+                       }
+               }
        }
 
        return true;
@@ -373,7 +399,7 @@ unsigned int GPU_select_end(void)
                                DepthID *depth_last = NULL;
                                for (unsigned int i = 0; i < qsd->rect_len; 
i++) {
                                        const unsigned int id = 
qsd->nearest.rect_id[i];
-                                       if (id != 0xffffffff) {
+                                       if (id != SELECT_ID_NONE) {
                                                const float depth = 
qsd->rect_depth[i];
                                                if (depth_last == NULL || 
depth_last->id != id) {
                                                        DepthID *d = 
&depth_data[depth_data_len_first_pass++];
@@ -410,8 +436,8 @@ unsigned int GPU_select_end(void)
                for (unsigned int i = 0; i < depth_data_len; i++) {
                        if (hits < maxhits) {
                                g_query_state.buffer[hits * 4] = 1;
-                               g_query_state.buffer[hits * 4 + 1] = 0xFFFF;
-                               g_query_state.buffer[hits * 4 + 2] = 0xFFFF;
+                               g_query_state.buffer[hits * 4 + 1] = 0xFFFF;  
/* TODO, depth near */
+                               g_query_state.buffer[hits * 4 + 2] = 0xFFFF;  
/* TODO, depth far */
                                g_query_state.buffer[hits * 4 + 3] = 
depth_data[i].id;
 
                                hits++;
@@ -449,15 +475,33 @@ unsigned int GPU_select_end(void)
                        unsigned int result;
                        glGetQueryObjectuiv(g_query_state.queries[i], 
GL_QUERY_RESULT, &result);
                        if (result > 0) {
-                               int j;
-                               /* search in buffer and make selected object 
first */
-                               for (j = 0; j < g_query_state.oldhits; j++) {
-                                       if (g_query_state.buffer[j * 4 + 3] == 
g_query_state.id[i]) {
-                                               g_query_state.buffer[j * 4 + 1] 
= 0;
-                                               g_query_state.buffer[j * 4 + 2] 
= 0;
+                               if (g_query_state.mode != 
GPU_SELECT_NEAREST_SECOND_PASS) {
+                                       int maxhits = g_query_state.bufsize / 4;
+
+                                       if (hits < maxhits) {
+                                               g_query_state.buffer[hits * 4] 
= 1;
+                                               g_query_state.buffer[hits * 4 + 
1] = 0xFFFF;
+                                               g_query_state.buffer[hits * 4 + 
2] = 0xFFFF;
+                                               g_query_state.buffer[hits * 4 + 
3] = g_query_state.id[i];
+
+                                               hits++;
+                                       }
+                                       else {
+                                               hits = -1;
+                                               break;
                                        }
                                }
-                               break;
+                               else {
+                                       int j;
+                                       /* search in buffer and make selected 
object first */
+                                       for (j = 0; j < g_query_state.oldhits; 
j++) {
+                                               if (g_query_state.buffer[j * 4 
+ 3] == g_query_state.id[i]) {
+                                                       g_query_state.buffer[j 
* 4 + 1] = 0;
+                                                       g_query_state.buffer[j 
* 4 + 2] = 0;
+                                               }
+                                       }
+                                       break;
+                               }
                        }
                }

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

Reply via email to