[Bf-blender-cvs] [48a7c7544e] temp-select-pick: Minor edits
Campbell Barton
noreply at git.blender.org
Wed Mar 8 07:31:55 CET 2017
Commit: 48a7c7544ea2943751a460aabddcba85d3c52177
Author: Campbell Barton
Date: Wed Mar 8 17:33:56 2017 +1100
Branches: temp-select-pick
https://developer.blender.org/rB48a7c7544ea2943751a460aabddcba85d3c52177
Minor edits
===================================================================
M source/blender/gpu/intern/gpu_select.c
M source/blender/gpu/intern/gpu_select_pick.c
===================================================================
diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index 79dd4fa06b..928f325393 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -34,7 +34,7 @@
#include "GPU_select.h"
#include "GPU_extensions.h"
#include "GPU_glew.h"
-
+
#include "MEM_guardedalloc.h"
#include "DNA_userdef_types.h"
@@ -45,8 +45,13 @@
/* Internal algorithm used */
enum {
+ /** GL_SELECT, legacy OpenGL selection */
ALGO_GL_LEGACY = 1,
+ /** glBegin/EndQuery(GL_SAMPLES_PASSED... ), `gpu_select_query.c`
+ * Only sets 4th component (ID) correctly. */
ALGO_GL_QUERY = 2,
+ /** Read depth buffer for every drawing pass and extract depths, `gpu_select_pick.c`
+ * Only sets 4th component (ID) correctly. */
ALGO_GL_PICK = 3,
};
@@ -188,6 +193,7 @@ bool GPU_select_query_check_active(void)
* Caching
*
* Support multiple begin/end's as long as they are within the initial region.
+ * Currently only used by ALGO_GL_PICK.
*/
void GPU_select_cache_begin(void)
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index cf023cfad8..ad6d119bd6 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -41,6 +41,8 @@
#include "BLI_listbase.h"
+#include "BLI_math_vector.h"
+
#include "BLI_utildefines.h"
#include "gpu_select_private.h"
@@ -66,13 +68,14 @@ typedef struct SubRectStride {
static void rect_subregion_stride_calc(const rcti *src, const rcti *dst, SubRectStride *r_sub)
{
const int src_x = BLI_rcti_size_x(src);
- const int src_y = BLI_rcti_size_y(src);
+ // const int src_y = BLI_rcti_size_y(src);
const int dst_x = BLI_rcti_size_x(dst);
const int dst_y = BLI_rcti_size_y(dst);
const int x = dst->xmin - src->xmin;
const int y = dst->ymin - src->ymin;
- BLI_assert(dst_x <= src_x && dst_y <= src_y);
+ BLI_assert(src->xmin <= dst->xmin && src->ymin <= dst->ymin &&
+ src->ymax >= dst->ymax && src->ymax >= dst->ymax);
BLI_assert(x >= 0 && y >= 0);
r_sub->start = (src_x * y) + x;
@@ -138,31 +141,28 @@ typedef struct GPUPickState {
/* mode of operation */
char mode;
- /* OpenGL drawing, never use when (is_cached == false). */
+ /* OpenGL drawing, never use when (is_cached == true). */
struct {
DepthBufCache *rect_depth;
- /* scratch buffer, avoid allocs every time */
+ /* Scratch buffer, avoid allocs every time (when not caching) */
DepthBufCache *rect_depth_test;
- /* Pass to glReadPixels (x,y,w,h) */
+ /* Pass to glReadPixels (x, y, w, h) */
int clip_readpixels[4];
+ /* Set after first draw */
bool is_init;
unsigned int prev_id;
} gl;
- /* Data stored in 'cache' and 'gl' */
+ /* src: data stored in 'cache' and 'gl',
+ * dst: use when cached region is smaller (where src -> dst isn't 1:1) */
struct {
rcti clip_rect;
unsigned int rect_len;
- } src;
-
- /* Use when cached region is smaller (where src -> dst isn't 1:1) */
- struct {
- rcti clip_rect;
- unsigned int rect_len;
- } dst;
+ } src, dst;
+ /* Store cache between `GPU_select_cache_begin/end` */
bool use_cache;
bool is_cached;
struct {
@@ -170,6 +170,7 @@ typedef struct GPUPickState {
* src.clip_rect -> dst.clip_rect */
SubRectStride sub_rect;
+ /* List of DepthBufCache, sized of 'src.clip_rect' */
ListBase bufs;
} cache;
@@ -187,9 +188,9 @@ typedef struct GPUPickState {
unsigned int *rect_id;
} nearest;
};
-
} GPUPickState;
+
static GPUPickState g_pick_state = {0};
void gpu_select_pick_begin(
@@ -242,9 +243,7 @@ void gpu_select_pick_begin(
#if 0
glReadPixels(UNPACK4(ps->gl.clip_readpixels), GL_DEPTH_COMPONENT, GL_FLOAT, ps->gl.rect_depth->buf);
#else
- for (unsigned int i = 0; i < rect_len; i++) {
- ps->gl.rect_depth->buf[i] = 1.0;
- }
+ copy_vn_fl(ps->gl.rect_depth->buf, rect_len, 1.0);
#endif
ps->gl.is_init = false;
@@ -262,6 +261,7 @@ void gpu_select_pick_begin(
}
}
else {
+ /* Using cache (ps->is_cached == true) */
/* src.clip_rect -> dst.clip_rect */
rect_subregion_stride_calc(&ps->src.clip_rect, &ps->dst.clip_rect, &ps->cache.sub_rect);
BLI_assert(ps->gl.rect_depth == NULL);
@@ -274,6 +274,7 @@ void gpu_select_pick_begin(
ps->all.hits_len_alloc = ALLOC_DEPTHS;
}
else {
+ /* Set to 0xff for SELECT_ID_NONE */
ps->nearest.rect_id = MEM_mallocN(sizeof(unsigned int) * ps->dst.rect_len, __func__);
memset(ps->nearest.rect_id, 0xff, sizeof(unsigned int) * ps->dst.rect_len);
}
@@ -291,7 +292,7 @@ static void gpu_select_load_id_pass(const DepthBufCache *rect_depth, const Depth
/* find the best depth for this pass and store in 'all.hits' */
float depth_best = FLT_MAX;
-#define UPDATE_DEPTH_TEST() \
+#define EVAL_TEST() \
if (*curr != *prev) { \
if (depth_best > *curr) { \
depth_best = *curr; \
@@ -304,7 +305,7 @@ static void gpu_select_load_id_pass(const DepthBufCache *rect_depth, const Depth
BLI_assert(ps->src.rect_len == ps->dst.rect_len);
const unsigned int rect_len = ps->src.rect_len;
for (unsigned int i = 0; i < rect_len; i++, curr++, prev++) {
- UPDATE_DEPTH_TEST();
+ EVAL_TEST();
}
}
else {
@@ -314,14 +315,14 @@ static void gpu_select_load_id_pass(const DepthBufCache *rect_depth, const Depth
for (unsigned int i = 0; i < ps->cache.sub_rect.len; i++) {
const float *prev_final = prev + ps->cache.sub_rect.span;
for (; prev < prev_final; prev++, curr++) {
- UPDATE_DEPTH_TEST();
+ EVAL_TEST();
}
prev += ps->cache.sub_rect.skip;
curr += ps->cache.sub_rect.skip;
}
}
-#undef UPDATE_DEPTH_TEST
+#undef EVAL_TEST
/* ensure enough space */
if (UNLIKELY(ps->all.hits_len == ps->all.hits_len_alloc)) {
@@ -337,7 +338,7 @@ static void gpu_select_load_id_pass(const DepthBufCache *rect_depth, const Depth
if (prev_id != SELECT_ID_NONE) {
unsigned int *id_ptr = ps->nearest.rect_id;
-#define UPDATE_ID_TEST() \
+#define EVAL_TEST() \
if (*curr != *prev) { \
*id_ptr = prev_id; \
} ((void)0)
@@ -348,7 +349,7 @@ static void gpu_select_load_id_pass(const DepthBufCache *rect_depth, const Depth
BLI_assert(ps->src.rect_len == ps->dst.rect_len);
const unsigned int rect_len = ps->src.rect_len;
for (unsigned int i = 0; i < rect_len; i++, curr++, prev++, id_ptr++) {
- UPDATE_ID_TEST();
+ EVAL_TEST();
}
}
else {
@@ -358,14 +359,14 @@ static void gpu_select_load_id_pass(const DepthBufCache *rect_depth, const Depth
for (unsigned int i = 0; i < ps->cache.sub_rect.len; i++) {
const float *prev_final = prev + ps->cache.sub_rect.span;
for (; prev < prev_final; prev++, curr++, id_ptr++) {
- UPDATE_ID_TEST();
+ EVAL_TEST();
}
prev += ps->cache.sub_rect.skip;
curr += ps->cache.sub_rect.skip;
}
}
-#undef UPDATE_ID_TEST
+#undef EVAL_TEST
}
}
@@ -453,7 +454,7 @@ unsigned int gpu_select_pick_end(void)
* when contiguous ID's are found - update their closest depth.
* This isn't essential but means there is less data to sort. */
-#define STORE_ID_TEST(i_src, i_dst) \
+#define EVAL_TEST(i_src, i_dst) \
{ \
const unsigned int id = ps->nearest.rect_id[i_dst]; \
if (id != SELECT_ID_NONE) { \
@@ -473,7 +474,7 @@ unsigned int gpu_select_pick_end(void)
DepthID *depth_last = NULL;
if (ps->is_cached == false) {
for (unsigned int i = 0; i < ps->src.rect_len; i++) {
- STORE_ID_TEST(i, i);
+ EVAL_TEST(i, i);
}
}
else {
@@ -482,14 +483,14 @@ unsigned int gpu_select_pick_end(void)
for (unsigned int j = 0; j < ps->cache.sub_rect.len; j++) {
const unsigned int i_src_final = i_src + ps->cache.sub_rect.span;
for (; i_src < i_src_final; i_src++, i_dst++) {
- STORE_ID_TEST(i_src, i_dst);
+ EVAL_TEST(i_src, i_dst);
}
i_src += ps->cache.sub_rect.skip;
}
}
}
-#undef STORE_ID_TEST
+#undef EVAL_TEST
qsort(depth_data, depth_data_len_first_pass, sizeof(DepthID), depth_id_cmp);
@@ -513,22 +514,21 @@ unsigned int gpu_select_pick_end(void)
* so the final hit-list is sorted by depth (nearest first) */
unsigned int hits = 0;
- qsort(depth_data, depth_data_len, sizeof(DepthID), depth_cmp);
+ if (depth_data_len > maxhits) {
+ hits = -1;
+ }
+ else {
+ qsort(depth_data, depth_data_len, sizeof(DepthID), depth_cmp);
- for (unsigned int i = 0; i < depth_data_len; i++) {
- if (hits < maxhits) {
+ for (unsigned int i = 0; i < depth_data_len; i++) {
/* first 3 are dummy values */
g_pick_state.buffer[hits][0] = 1;
g_pick_state.buffer[hits][1] = 0x0;
g_pick_state.buffer[hits][2] = 0x0;
g_pick_state.buffer[hits][3] = depth_data[i].id;
-
hits++;
}
- else {
- hits = -1;
- break;
- }
+ BLI_assert(hits < maxhits);
}
MEM_freeN(depth_data);
More information about the Bf-blender-cvs
mailing list