Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormano-wii <germano.costa@ig.com.br>2019-03-15 22:02:55 +0300
committermano-wii <germano.costa@ig.com.br>2019-03-15 23:02:48 +0300
commit681661dbed121c7b81e9129c57df5eadb03c1009 (patch)
tree8802195c72af13e1bb7324131024cc98fb5971a7 /source/blender/draw
parent4510f88d00a721a3d4ad3aa675050723eec2292c (diff)
GPU: Simplify select shaders.
The shaders are: `GPU_SHADER_3D_FLAT_SELECT_ID` and `GPU_SHADER_3D_UNIFORM_SELECT_ID`. This commit allows the drawing of the mesh select ids to be done on a 32UI format texture. This simplifies the shader that previously acted on the backbuffer and had to do an uint to rgba conversion. Differential Revision: https://developer.blender.org/D4350
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/DRW_engine.h4
-rw-r--r--source/blender/draw/intern/draw_manager.c144
2 files changed, 129 insertions, 19 deletions
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index e261de3c900..68d4ef04f95 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -123,6 +123,10 @@ void DRW_draw_depth_loop(
struct Depsgraph *depsgraph,
struct ARegion *ar, struct View3D *v3d);
+void DRW_framebuffer_select_id_setup(struct ARegion *ar, const bool clear);
+void DRW_framebuffer_select_id_release(struct ARegion *ar);
+void DRW_framebuffer_select_id_read(const struct rcti *rect, uint *r_buf);
+
/* grease pencil render */
bool DRW_render_check_grease_pencil(struct Depsgraph *depsgraph);
void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index a34d2532bb5..fb30e4391e7 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -2015,20 +2015,26 @@ void DRW_custom_pipeline(
}
static struct DRWSelectBuffer {
- struct GPUFrameBuffer *framebuffer;
+ struct GPUFrameBuffer *framebuffer_depth_only;
+ struct GPUFrameBuffer *framebuffer_select_id;
struct GPUTexture *texture_depth;
+ struct GPUTexture *texture_u32;
} g_select_buffer = {NULL};
-static void draw_select_framebuffer_setup(const rcti *rect)
+static void draw_select_framebuffer_depth_only_setup(const rcti *rect)
{
- if (g_select_buffer.framebuffer == NULL) {
- g_select_buffer.framebuffer = GPU_framebuffer_create();
+ float size[2];
+ size[0] = BLI_rcti_size_x(rect);
+ size[1] = BLI_rcti_size_y(rect);
+
+ if (g_select_buffer.framebuffer_depth_only == NULL) {
+ g_select_buffer.framebuffer_depth_only = GPU_framebuffer_create();
+ g_select_buffer.framebuffer_select_id = GPU_framebuffer_create();
}
- /* If size mismatch recreate the texture. */
if ((g_select_buffer.texture_depth != NULL) &&
- ((GPU_texture_width(g_select_buffer.texture_depth) != BLI_rcti_size_x(rect)) ||
- (GPU_texture_height(g_select_buffer.texture_depth) != BLI_rcti_size_y(rect))))
+ ((GPU_texture_width(g_select_buffer.texture_depth) != size[0]) ||
+ (GPU_texture_height(g_select_buffer.texture_depth) != size[1])))
{
GPU_texture_free(g_select_buffer.texture_depth);
g_select_buffer.texture_depth = NULL;
@@ -2036,13 +2042,50 @@ static void draw_select_framebuffer_setup(const rcti *rect)
if (g_select_buffer.texture_depth == NULL) {
g_select_buffer.texture_depth = GPU_texture_create_2D(
- BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), GPU_DEPTH_COMPONENT24, NULL, NULL);
+ size[0], size[1], GPU_DEPTH_COMPONENT24, NULL, NULL);
- GPU_framebuffer_texture_attach(g_select_buffer.framebuffer, g_select_buffer.texture_depth, 0, 0);
+ GPU_framebuffer_texture_attach(
+ g_select_buffer.framebuffer_depth_only,
+ g_select_buffer.texture_depth, 0, 0);
- if (!GPU_framebuffer_check_valid(g_select_buffer.framebuffer, NULL)) {
- printf("Error invalid selection framebuffer\n");
- }
+ GPU_framebuffer_texture_attach(
+ g_select_buffer.framebuffer_select_id,
+ g_select_buffer.texture_depth, 0, 0);
+
+ GPU_framebuffer_check_valid(
+ g_select_buffer.framebuffer_depth_only, __func__);
+
+ GPU_framebuffer_check_valid(
+ g_select_buffer.framebuffer_select_id, __func__);
+ }
+}
+
+static void draw_select_framebuffer_select_id_setup(const rcti *rect)
+{
+ float size[2];
+ size[0] = BLI_rcti_size_x(rect);
+ size[1] = BLI_rcti_size_y(rect);
+
+ draw_select_framebuffer_depth_only_setup(rect);
+
+ if ((g_select_buffer.texture_u32 != NULL) &&
+ ((GPU_texture_width(g_select_buffer.texture_u32) != size[0]) ||
+ (GPU_texture_height(g_select_buffer.texture_u32) != size[1])))
+ {
+ GPU_texture_free(g_select_buffer.texture_u32);
+ g_select_buffer.texture_u32 = NULL;
+ }
+
+ if (g_select_buffer.texture_u32 == NULL) {
+ g_select_buffer.texture_u32 = GPU_texture_create_2D(
+ size[0], size[1], GPU_R32UI, NULL, NULL);
+
+ GPU_framebuffer_texture_attach(
+ g_select_buffer.framebuffer_select_id,
+ g_select_buffer.texture_u32, 0, 0);
+
+ GPU_framebuffer_check_valid(
+ g_select_buffer.framebuffer_select_id, __func__);
}
}
@@ -2209,9 +2252,9 @@ void DRW_draw_select_loop(
}
/* Setup framebuffer */
- draw_select_framebuffer_setup(rect);
- GPU_framebuffer_bind(g_select_buffer.framebuffer);
- GPU_framebuffer_clear_depth(g_select_buffer.framebuffer, 1.0f);
+ draw_select_framebuffer_depth_only_setup(rect);
+ GPU_framebuffer_bind(g_select_buffer.framebuffer_depth_only);
+ GPU_framebuffer_clear_depth(g_select_buffer.framebuffer_depth_only, 1.0f);
/* Start Drawing */
DRW_state_reset();
@@ -2315,9 +2358,9 @@ void DRW_draw_depth_loop(
GPU_viewport_size_set(viewport, (const int[2]){ar->winx, ar->winy});
/* Setup framebuffer */
- draw_select_framebuffer_setup(&ar->winrct);
- GPU_framebuffer_bind(g_select_buffer.framebuffer);
- GPU_framebuffer_clear_depth(g_select_buffer.framebuffer, 1.0f);
+ draw_select_framebuffer_depth_only_setup(&ar->winrct);
+ GPU_framebuffer_bind(g_select_buffer.framebuffer_depth_only);
+ GPU_framebuffer_clear_depth(g_select_buffer.framebuffer_depth_only, 1.0f);
DST.viewport = viewport;
DST.options.is_depth = true;
@@ -2421,6 +2464,67 @@ void DRW_draw_depth_loop(
GPU_matrix_pop_projection();
}
+
+/* Set an opengl context to be used with shaders that draw on U32 colors. */
+void DRW_framebuffer_select_id_setup(ARegion *ar, const bool clear)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ DRW_opengl_context_enable();
+
+ /* Setup framebuffer */
+ draw_select_framebuffer_select_id_setup(&ar->winrct);
+ GPU_framebuffer_bind(g_select_buffer.framebuffer_select_id);
+
+ /* dithering and AA break color coding, so disable */
+ glDisable(GL_DITHER);
+
+ GPU_depth_test(true);
+
+ if (clear) {
+ GPU_framebuffer_clear_color_depth(
+ g_select_buffer.framebuffer_select_id, (const float[4]){0.0f}, 1.0f);
+ }
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_set(rv3d);
+ }
+}
+
+
+/* Ends the context for selection and restoring the previous one. */
+void DRW_framebuffer_select_id_release(ARegion *ar)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_disable();
+ }
+
+ GPU_framebuffer_restore();
+
+ GPU_depth_test(false);
+ glEnable(GL_DITHER);
+
+ DRW_opengl_context_disable();
+}
+
+
+/* Read a block of pixels from the select frame buffer. */
+void DRW_framebuffer_select_id_read(const rcti *rect, uint *r_buf)
+{
+ DRW_opengl_context_enable();
+ GPU_framebuffer_bind(g_select_buffer.framebuffer_select_id);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+
+ glReadPixels(rect->xmin, rect->ymin,
+ BLI_rcti_size_x(rect), BLI_rcti_size_y(rect),
+ GL_RED_INTEGER, GL_UNSIGNED_INT, r_buf);
+
+ GPU_framebuffer_restore();
+ DRW_opengl_context_disable();
+}
+
/** \} */
@@ -2612,8 +2716,10 @@ void DRW_engines_free(void)
DRW_opengl_context_enable();
+ DRW_TEXTURE_FREE_SAFE(g_select_buffer.texture_u32);
DRW_TEXTURE_FREE_SAFE(g_select_buffer.texture_depth);
- GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer);
+ GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer_select_id);
+ GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer_depth_only);
DRW_hair_free();
DRW_shape_cache_free();