[Bf-blender-cvs] [7a3e06b9f7] temp-select-pick: Added back multi-pass occlusion queries
Campbell Barton
noreply at git.blender.org
Mon Mar 6 08:41:49 CET 2017
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;
+ }
}
}
More information about the Bf-blender-cvs
mailing list