From cc0c971f84a2fa616c3f5df371f160d9d024fb08 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 20 Apr 2018 10:45:46 +0200 Subject: Workbench: Added the basics for the OverlayMode Implemented the face orientation overlay for testing. Overlay mode is only drawn when there are overlays to be rendered. The overlay mode is rendered before the object mode. --- source/blender/draw/CMakeLists.txt | 3 + source/blender/draw/intern/draw_manager.c | 7 + source/blender/draw/modes/draw_mode_engines.h | 1 + source/blender/draw/modes/overlay_mode.c | 185 +++++++++++++++++++++ .../shaders/overlay_face_orientation_frag.glsl | 10 ++ .../shaders/overlay_face_orientation_vert.glsl | 21 +++ source/blender/makesdna/DNA_view3d_types.h | 7 + source/blender/makesrna/intern/rna_space.c | 6 + 8 files changed, 240 insertions(+) create mode 100644 source/blender/draw/modes/overlay_mode.c create mode 100644 source/blender/draw/modes/shaders/overlay_face_orientation_frag.glsl create mode 100644 source/blender/draw/modes/shaders/overlay_face_orientation_vert.glsl (limited to 'source') diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index a59f1c5f1c1..d8143fef771 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -80,6 +80,7 @@ set(SRC modes/edit_surface_mode.c modes/edit_text_mode.c modes/object_mode.c + modes/overlay_mode.c modes/paint_texture_mode.c modes/paint_vertex_mode.c modes/paint_weight_mode.c @@ -234,6 +235,8 @@ data_to_c_simple(modes/shaders/edit_lattice_overlay_frag.glsl SRC) data_to_c_simple(modes/shaders/edit_lattice_overlay_loosevert_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_normals_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_normals_geom.glsl SRC) +data_to_c_simple(modes/shaders/overlay_face_orientation_frag.glsl SRC) +data_to_c_simple(modes/shaders/overlay_face_orientation_vert.glsl SRC) data_to_c_simple(modes/shaders/object_empty_image_frag.glsl SRC) data_to_c_simple(modes/shaders/object_empty_image_vert.glsl SRC) data_to_c_simple(modes/shaders/object_outline_resolve_frag.glsl SRC) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 2c1e8612d51..b620d1875d8 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -985,6 +985,11 @@ static void drw_engines_enable_from_mode(int mode) } } +static void drw_engines_enable_from_overlays(int draw_overlays) { + if (draw_overlays) { + use_drw_engine(&draw_engine_overlay_type); + } +} /** * Use for select and depth-drawing. */ @@ -1006,6 +1011,7 @@ static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_t drw_engines_enable_from_engine(engine_type, drawtype, drawtype_wireframe, drawtype_solid, drawtype_texture); if (DRW_state_draw_support()) { + drw_engines_enable_from_overlays(v3d->overlays); drw_engines_enable_from_object_mode(); drw_engines_enable_from_mode(mode); } @@ -1959,6 +1965,7 @@ void DRW_engines_register(void) DRW_engine_register(&draw_engine_edit_metaball_type); DRW_engine_register(&draw_engine_edit_surface_type); DRW_engine_register(&draw_engine_edit_text_type); + DRW_engine_register(&draw_engine_overlay_type); DRW_engine_register(&draw_engine_paint_texture_type); DRW_engine_register(&draw_engine_paint_vertex_type); DRW_engine_register(&draw_engine_paint_weight_type); diff --git a/source/blender/draw/modes/draw_mode_engines.h b/source/blender/draw/modes/draw_mode_engines.h index 23fedbba5a5..a1f769d244f 100644 --- a/source/blender/draw/modes/draw_mode_engines.h +++ b/source/blender/draw/modes/draw_mode_engines.h @@ -40,5 +40,6 @@ extern DrawEngineType draw_engine_paint_weight_type; extern DrawEngineType draw_engine_particle_type; extern DrawEngineType draw_engine_pose_type; extern DrawEngineType draw_engine_sculpt_type; +extern DrawEngineType draw_engine_overlay_type; #endif /* __DRAW_MODE_ENGINES_H__ */ \ No newline at end of file diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c new file mode 100644 index 00000000000..d7e87cf238f --- /dev/null +++ b/source/blender/draw/modes/overlay_mode.c @@ -0,0 +1,185 @@ +/* + * Copyright 2016, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Blender Institute + * + */ + +/** \file overlay_mode.c + * \ingroup draw_engine + */ + +#include "DRW_render.h" + +#include "GPU_shader.h" +#include "DNA_view3d_types.h" + +/* Structures */ +typedef struct OVERLAY_StorageList { + struct OVERLAY_PrivateData *g_data; +} OVERLAY_StorageList; + +typedef struct OVERLAY_PassList { + struct DRWPass *depth_pass; + struct DRWPass *face_orientation_pass; +} OVERLAY_PassList; + +typedef struct OVERLAY_Data { + void *engine_type; + DRWViewportEmptyList *fbl; + DRWViewportEmptyList *txl; + OVERLAY_PassList *psl; + OVERLAY_StorageList *stl; +} OVERLAY_Data; + +typedef struct OVERLAY_PrivateData { + DRWShadingGroup *depth_shgrp; + DRWShadingGroup *face_orientation_shgrp; + int overlays; +} OVERLAY_PrivateData; /* Transient data */ + +typedef struct OVERLAY_MaterialData { + /* Solid color */ + float color[3]; + + /* Linked shgroup for drawing */ + DRWShadingGroup *shgrp; +} OVERLAY_MaterialData; + +/* *********** STATIC *********** */ +static struct { + struct GPUShader *depth_sh; + + /* Solid flat mode */ + struct GPUShader *face_orientation_sh; + +} e_data = {NULL}; + +/* Shaders */ +extern char datatoc_overlay_face_orientation_frag_glsl[]; +extern char datatoc_overlay_face_orientation_vert_glsl[]; + + +/* Functions */ +static void overlay_engine_init(void *UNUSED(vedata)) +{ + if (!e_data.depth_sh) { + /* Depth pass */ + e_data.depth_sh = DRW_shader_create_3D_depth_only(); + + /* Solid flat */ + e_data.face_orientation_sh = DRW_shader_create(datatoc_overlay_face_orientation_vert_glsl, NULL, datatoc_overlay_face_orientation_frag_glsl, "\n"); + } +} + +static void overlay_cache_init(void *vedata) +{ + + OVERLAY_Data * data = (OVERLAY_Data *)vedata; + OVERLAY_PassList *psl = data->psl; + OVERLAY_StorageList *stl = data->stl; + + const DRWContextState *DCS = DRW_context_state_get(); + + if (!stl->g_data) { + /* Alloc transient pointers */ + stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); + } + + View3D *v3d = DCS->v3d; + if (v3d) { + stl->g_data->overlays = v3d->overlays; + } + else { + stl->g_data->overlays = 0; + } + + + /* Depth Pass */ + { + int state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS; + psl->depth_pass = DRW_pass_create("Depth Pass", state); + stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass); + } + + /* Face Orientation Pass */ + if (stl->g_data->overlays & V3D_OVERLAY_FACE_ORIENTATION) + { + int state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL; + psl->face_orientation_pass = DRW_pass_create("Face Orientation", state); + stl->g_data->face_orientation_shgrp = DRW_shgroup_create(e_data.face_orientation_sh, psl->face_orientation_pass); + } +} + +static void overlay_cache_populate(void *vedata, Object *ob) +{ + OVERLAY_Data * data = (OVERLAY_Data *)vedata; + OVERLAY_StorageList *stl = data->stl; + OVERLAY_PrivateData *pd = stl->g_data; + + if (!DRW_object_is_renderable(ob)) + return; + + struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); + if (geom) { + /* Depth */ + DRW_shgroup_call_add(pd->depth_shgrp, geom, ob->obmat); + + /* Face Orientation */ + if (stl->g_data->overlays & V3D_OVERLAY_FACE_ORIENTATION) { + DRW_shgroup_call_add(pd->face_orientation_shgrp, geom, ob->obmat); + } + } + +} + +static void overlay_cache_finish(void *UNUSED(vedata)) +{ +} + +static void overlay_draw_scene(void *vedata) +{ + OVERLAY_Data * data = (OVERLAY_Data *)vedata; + OVERLAY_PassList *psl = data->psl; + + DRW_draw_pass(psl->depth_pass); + DRW_draw_pass(psl->face_orientation_pass); +} + +static void overlay_engine_free(void) +{ + DRW_SHADER_FREE_SAFE(e_data.face_orientation_sh); +} + +static const DrawEngineDataSize overlay_data_size = DRW_VIEWPORT_DATA_SIZE(OVERLAY_Data); + +DrawEngineType draw_engine_overlay_type = { + NULL, NULL, + N_("OverlayEngine"), + &overlay_data_size, + &overlay_engine_init, + &overlay_engine_free, + &overlay_cache_init, + &overlay_cache_populate, + &overlay_cache_finish, + NULL, + &overlay_draw_scene, + NULL, + NULL, + NULL, +}; + diff --git a/source/blender/draw/modes/shaders/overlay_face_orientation_frag.glsl b/source/blender/draw/modes/shaders/overlay_face_orientation_frag.glsl new file mode 100644 index 00000000000..51ce67a13a2 --- /dev/null +++ b/source/blender/draw/modes/shaders/overlay_face_orientation_frag.glsl @@ -0,0 +1,10 @@ +uniform vec3 color_towards = vec3(0.0, 0.0, 1.0); +uniform vec3 color_outwards = vec3(1.0, 0.0, 0.0); + +out vec4 fragColor; + +flat in float facing; +void main() +{ + fragColor = vec4((facing < 0.0 ? color_towards: color_outwards)*abs(facing), 1.0); +} diff --git a/source/blender/draw/modes/shaders/overlay_face_orientation_vert.glsl b/source/blender/draw/modes/shaders/overlay_face_orientation_vert.glsl new file mode 100644 index 00000000000..e9518c25400 --- /dev/null +++ b/source/blender/draw/modes/shaders/overlay_face_orientation_vert.glsl @@ -0,0 +1,21 @@ + +uniform mat4 ModelViewProjectionMatrix; + +in vec3 pos; +in vec3 nor; + +uniform mat4 ProjectionMatrix; +uniform mat4 ModelViewMatrix; +uniform mat3 NormalMatrix; + +flat out float facing; + +void main() +{ + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); + vec3 view_normal = normalize(NormalMatrix * nor); + vec3 view_vec = (ProjectionMatrix[3][3] == 0.0) + ? normalize((ModelViewMatrix * vec4(pos, 1.0)).xyz) + : vec3(0.0, 0.0, 1.0); + facing = dot(view_vec, view_normal); +} diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 8953518778a..09710664e34 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -80,6 +80,10 @@ enum { V3D_LIGHTING_SCENE = 2 }; +enum { + V3D_OVERLAY_FACE_ORIENTATION = (1 << 0), +}; + typedef struct RegionView3D { float winmat[4][4]; /* GL_PROJECTION matrix */ @@ -248,6 +252,9 @@ typedef struct View3D { /* drawtype subtype (lighting) used when drawtype == OB_TEXTURE */ short drawtype_texture; + int overlays; + int pad5; + View3DDebug debug; } View3D; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 7d121f76016..962ff7747dc 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2336,6 +2336,12 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Viewport Lighting (Texture)", "Lighting Method for Texture Viewport Shading"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_viewport_shade_update"); + prop = RNA_def_property(srna, "show_face_orientation_overlay", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "overlays", V3D_OVERLAY_FACE_ORIENTATION); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Face Orientation", "Show the Face Orientation Overlay"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_viewport_shade_update"); + prop = RNA_def_property(srna, "local_view", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "localvd"); RNA_def_property_ui_text(prop, "Local View", -- cgit v1.2.3