[Bf-blender-cvs] [7acf1dbdedd] bitmap_visibility_gpu: Initial Commit: Use GPU to test the visibility of vertices.
mano-wii
noreply at git.blender.org
Tue Jul 30 19:34:08 CEST 2019
Commit: 7acf1dbdeddc63d991dc563f534409eb9b60be4d
Author: mano-wii
Date: Tue Jul 30 14:33:33 2019 -0300
Branches: bitmap_visibility_gpu
https://developer.blender.org/rB7acf1dbdeddc63d991dc563f534409eb9b60be4d
Initial Commit: Use GPU to test the visibility of vertices.
===================================================================
M source/blender/draw/CMakeLists.txt
M source/blender/draw/engines/select/select_engine.c
A source/blender/draw/engines/select/shaders/selection_id_3D_bitmap_vert.glsl
A source/blender/draw/engines/select/shaders/selection_id_bitmap_frag.glsl
===================================================================
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 664484d9a57..edc20039375 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -365,7 +365,9 @@ data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_shadow_resolve_frag.glsl
data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl SRC)
data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl SRC)
+data_to_c_simple(engines/select/shaders/selection_id_3D_bitmap_vert.glsl SRC)
data_to_c_simple(engines/select/shaders/selection_id_3D_vert.glsl SRC)
+data_to_c_simple(engines/select/shaders/selection_id_bitmap_frag.glsl SRC)
data_to_c_simple(engines/select/shaders/selection_id_frag.glsl SRC)
diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c
index f1fc9cbc0d6..714c3456752 100644
--- a/source/blender/draw/engines/select/select_engine.c
+++ b/source/blender/draw/engines/select/select_engine.c
@@ -22,6 +22,9 @@
* Engine for drawing a selection map where the pixels indicate the selection indices.
*/
+#include "MEM_guardedalloc.h"
+
+#include "BLI_bitmap.h"
#include "BLI_rect.h"
#include "BKE_editmesh.h"
@@ -61,6 +64,8 @@ typedef struct SELECTID_PassList {
struct DRWPass *select_id_face_pass;
struct DRWPass *select_id_edge_pass;
struct DRWPass *select_id_vert_pass;
+
+ struct DRWPass *visibility_vert_pass;
} SELECTID_PassList;
typedef struct SELECTID_Data {
@@ -75,6 +80,7 @@ typedef struct SELECTID_Shaders {
/* Depth Pre Pass */
struct GPUShader *select_id_flat;
struct GPUShader *select_id_uniform;
+ struct GPUShader *select_id_bitmap;
} SELECTID_Shaders;
/* *********** STATIC *********** */
@@ -94,6 +100,8 @@ static struct {
struct Depsgraph *depsgraph;
short select_mode;
+
+ BLI_bitmap *vert_visibility_mask;
} context;
} e_data = {{{NULL}}}; /* Engine data */
@@ -103,6 +111,8 @@ typedef struct SELECTID_PrivateData {
DRWShadingGroup *shgrp_edge;
DRWShadingGroup *shgrp_vert;
+ DRWShadingGroup *shgrp_visibly_vert;
+
DRWView *view_faces;
DRWView *view_edges;
DRWView *view_verts;
@@ -129,6 +139,8 @@ struct BaseOffset {
extern char datatoc_common_view_lib_glsl[];
extern char datatoc_selection_id_3D_vert_glsl[];
extern char datatoc_selection_id_frag_glsl[];
+extern char datatoc_selection_id_3D_bitmap_vert_glsl[];
+extern char datatoc_selection_id_bitmap_frag_glsl[];
/* -------------------------------------------------------------------- */
/** \name Selection Utilities
@@ -327,6 +339,7 @@ static void select_engine_init(void *vedata)
.defs = (const char *[]){sh_cfg_data->def, NULL},
});
}
+
if (!sh_data->select_id_uniform) {
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
sh_data->select_id_uniform = GPU_shader_create_from_arrays({
@@ -339,6 +352,19 @@ static void select_engine_init(void *vedata)
});
}
+ /* TODO: Create on demand */
+ if (!sh_data->select_id_bitmap) {
+ const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg];
+ sh_data->select_id_bitmap = GPU_shader_create_from_arrays({
+ .vert = (const char *[]){sh_cfg_data->lib,
+ datatoc_common_view_lib_glsl,
+ datatoc_selection_id_3D_bitmap_vert_glsl,
+ NULL},
+ .frag = (const char *[]){datatoc_selection_id_bitmap_frag_glsl, NULL},
+ .defs = (const char *[]){sh_cfg_data->def, NULL},
+ });
+ }
+
if (!stl->g_data) {
/* Alloc transient pointers */
stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
@@ -379,11 +405,18 @@ static void select_cache_init(void *vedata)
DRW_shgroup_uniform_float_copy(stl->g_data->shgrp_vert, "sizeVertex", G_draw.block.sizeVertex);
+ psl->visibility_vert_pass = DRW_pass_create("Vert Visibility Pass",
+ DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL);
+
+ stl->g_data->shgrp_visibly_vert = DRW_shgroup_create(sh_data->select_id_bitmap,
+ psl->visibility_vert_pass);
+
if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_state_enable(stl->g_data->shgrp_face_unif, DRW_STATE_CLIP_PLANES);
DRW_shgroup_state_enable(stl->g_data->shgrp_face_flat, DRW_STATE_CLIP_PLANES);
DRW_shgroup_state_enable(stl->g_data->shgrp_edge, DRW_STATE_CLIP_PLANES);
DRW_shgroup_state_enable(stl->g_data->shgrp_vert, DRW_STATE_CLIP_PLANES);
+ DRW_shgroup_state_enable(stl->g_data->shgrp_visibly_vert, DRW_STATE_CLIP_PLANES);
}
}
@@ -417,6 +450,17 @@ static void select_cache_populate(void *vedata, Object *ob)
&base_ofs->edge,
&base_ofs->face);
+ if (true) {
+ SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl;
+ if (ob->type == OB_MESH && ob->mode & OB_MODE_EDIT) {
+ Mesh *me = ob->data;
+ struct GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me);
+ DRWShadingGroup *vert_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_visibly_vert);
+ DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", *(int *)&offset);
+ DRW_shgroup_call(vert_shgrp, geom_verts, ob);
+ }
+ }
+
base_ofs->offset = offset;
e_data.context.last_index_drawn = base_ofs->vert;
}
@@ -443,6 +487,31 @@ static void select_draw_scene(void *vedata)
DRW_view_set_active(stl->g_data->view_verts);
DRW_draw_pass(psl->select_id_vert_pass);
+
+ if (true) {
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ uint tot_index = DRW_select_context_elem_len();
+ DRW_shgroup_uniform_texture_ref(stl->g_data->shgrp_visibly_vert, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_int_copy(stl->g_data->shgrp_visibly_vert, "tot_index", *(int *)&tot_index);
+
+ int num_blocks = _BITMAP_NUM_BLOCKS(tot_index);
+ GPUTexture *bitmap_tex = GPU_texture_create_1d(num_blocks, GPU_R32UI, NULL, NULL);
+ GPUFrameBuffer *bitmap_fb = GPU_framebuffer_create();
+ GPU_framebuffer_texture_attach(bitmap_fb, bitmap_tex, 0, 0);
+ BLI_assert(GPU_framebuffer_check_valid(bitmap_fb, NULL));
+
+ GPU_framebuffer_bind(bitmap_fb);
+ GPU_framebuffer_clear_color(bitmap_fb, (const float[4]){0.0f});
+
+ DRW_draw_pass(psl->visibility_vert_pass);
+
+ MEM_SAFE_FREE(e_data.context.vert_visibility_mask);
+ e_data.context.vert_visibility_mask = GPU_texture_read(bitmap_tex, GPU_DATA_UNSIGNED_INT, 0);
+ GPU_finish();
+
+ GPU_framebuffer_free(bitmap_fb);
+ GPU_texture_free(bitmap_tex);
+ }
}
static void select_engine_free(void)
@@ -451,11 +520,13 @@ static void select_engine_free(void)
SELECTID_Shaders *sh_data = &e_data.sh_data[sh_data_index];
DRW_SHADER_FREE_SAFE(sh_data->select_id_flat);
DRW_SHADER_FREE_SAFE(sh_data->select_id_uniform);
+ DRW_SHADER_FREE_SAFE(sh_data->select_id_bitmap);
}
DRW_TEXTURE_FREE_SAFE(e_data.texture_u32);
GPU_FRAMEBUFFER_FREE_SAFE(e_data.framebuffer_select_id);
MEM_SAFE_FREE(e_data.context.base_array_index_offsets);
+ MEM_SAFE_FREE(e_data.context.vert_visibility_mask);
}
/** \} */
@@ -529,6 +600,11 @@ uint DRW_select_context_elem_len(void)
return e_data.context.last_index_drawn;
}
+BLI_bitmap *DRW_select_context_vert_visibility_mask(void)
+{
+ return e_data.context.vert_visibility_mask;
+}
+
/* Read a block of pixels from the select frame buffer. */
void DRW_framebuffer_select_id_read(const rcti *rect, uint *r_buf)
{
diff --git a/source/blender/draw/engines/select/shaders/selection_id_3D_bitmap_vert.glsl b/source/blender/draw/engines/select/shaders/selection_id_3D_bitmap_vert.glsl
new file mode 100644
index 00000000000..a7d5d4c2739
--- /dev/null
+++ b/source/blender/draw/engines/select/shaders/selection_id_3D_bitmap_vert.glsl
@@ -0,0 +1,46 @@
+
+/* Copied from BLI_bitmap.h */
+/* 2^5 = 32 (bits) */
+#define _BITMAP_POWER 5u
+/* 0b11111 */
+#define _BITMAP_MASK 31u
+
+/* number of blocks needed to hold '_tot' bits */
+#define _BITMAP_NUM_BLOCKS(_tot) (((_tot) >> _BITMAP_POWER) + 1)
+
+uniform int offset;
+uniform int tot_index;
+uniform sampler2D depthBuffer;
+
+in vec3 pos;
+in uint color;
+
+flat out uint bit;
+
+float normalize_factor = 2.0 / _BITMAP_NUM_BLOCKS(tot_index);
+
+void main()
+{
+ vec3 world_pos = point_object_to_world(pos);
+ vec4 ndc_pos = point_world_to_ndc(world_pos);
+
+ float depth = texture(depthBuffer, ndc_pos.xy).x;
+ float r_pos;
+
+ if (false && (depth * ndc_pos.w) > ndc_pos.z) {
+ bit = 0u;
+ r_pos = -1.0;
+ }
+ else {
+ uint index = floatBitsToUint(intBitsToFloat(offset)) + color;
+ bit = 1u << (index & _BITMAP_MASK);
+ r_pos = (index >> _BITMAP_POWER) * normalize_factor - 1.0;
+ }
+
+ gl_Position = vec4(r_pos, 0.0, 0.0, 1.0);
+ gl_PointSize = 1.0;
+
+#ifdef USE_WORLD_CLIP_PLANES
+ world_clip_planes_calc_clip_distance(world_pos);
+#endif
+}
diff --git a/source/blender/draw/engines/select/shaders/selection_id_bitmap_frag.glsl b/source/blender/draw/engines/select/shaders/selection_id_bitmap_frag.glsl
new file mode 100644
index 00000000000..f36ab75db68
--- /dev/null
+++ b/source/blender/draw/engines/select/shaders/selection_id_bitmap_frag.glsl
@@ -0,0 +1,8 @@
+
+flat in uint bit;
+out uint fragColor;
+
+void main()
+{
+ fragColor = bit;
+}
More information about the Bf-blender-cvs
mailing list