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.
This commit is contained in:
Jeroen Bakker 2018-04-20 10:45:46 +02:00
parent 95e39943ef
commit cc0c971f84
9 changed files with 241 additions and 0 deletions

View File

@ -3473,6 +3473,7 @@ class VIEW3D_PT_view3d_display(Panel):
col.prop(view, "show_outline_selected")
col.prop(view, "show_all_objects_origin")
col.prop(view, "show_relationship_lines")
col.prop(view, "show_face_orientation_overlay")
col = layout.column()
col.active = display_all

View File

@ -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)

View File

@ -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);

View File

@ -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__ */

View File

@ -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,
};

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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",