diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-05-31 20:01:22 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-05-31 20:09:20 +0300 |
commit | bf4ce5755f3699105a1e97793db63f9fc8f7ad9a (patch) | |
tree | e9c6855b3305e26dd4def29cea78253e7b7fa507 /source/blender/draw/modes/overlay_mode.c | |
parent | 712885c30ef2a8dbde91b7d8b4ffb9784a70fca5 (diff) |
Overlay: Add Wireframe overlay.
This overlay is showing mesh topology. It is usable with transparency
even if the mesh order can mess up with the expected result (some object
more prominent than others).
Edge thickness and alpha values are hardcoded for now but can easily be
added to theme or object settings.
Diffstat (limited to 'source/blender/draw/modes/overlay_mode.c')
-rw-r--r-- | source/blender/draw/modes/overlay_mode.c | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c index c4b64e03c48..505472460a1 100644 --- a/source/blender/draw/modes/overlay_mode.c +++ b/source/blender/draw/modes/overlay_mode.c @@ -25,6 +25,8 @@ #include "DNA_view3d_types.h" +#include "BKE_object.h" + #include "GPU_shader.h" #include "DRW_render.h" @@ -37,6 +39,7 @@ typedef struct OVERLAY_StorageList { typedef struct OVERLAY_PassList { struct DRWPass *face_orientation_pass; + struct DRWPass *face_wireframe_pass; } OVERLAY_PassList; typedef struct OVERLAY_Data { @@ -56,12 +59,18 @@ typedef struct OVERLAY_PrivateData { static struct { /* Face orientation shader */ struct GPUShader *face_orientation_sh; + /* Wireframe shader */ + struct GPUShader *face_wireframe_sh; } e_data = {NULL}; /* Shaders */ extern char datatoc_overlay_face_orientation_frag_glsl[]; extern char datatoc_overlay_face_orientation_vert_glsl[]; +extern char datatoc_overlay_face_wireframe_vert_glsl[]; +extern char datatoc_overlay_face_wireframe_frag_glsl[]; + +extern struct GlobalsUboStorage ts; /* draw_common.c */ /* Functions */ static void overlay_engine_init(void *vedata) @@ -77,7 +86,14 @@ static void overlay_engine_init(void *vedata) if (!e_data.face_orientation_sh) { /* Face orientation */ e_data.face_orientation_sh = DRW_shader_create( - datatoc_overlay_face_orientation_vert_glsl, NULL, datatoc_overlay_face_orientation_frag_glsl, "\n"); + datatoc_overlay_face_orientation_vert_glsl, NULL, + datatoc_overlay_face_orientation_frag_glsl, NULL); + } + + if (!e_data.face_wireframe_sh) { + e_data.face_wireframe_sh = DRW_shader_create( + datatoc_overlay_face_wireframe_vert_glsl, NULL, + datatoc_overlay_face_wireframe_frag_glsl, NULL); } } @@ -99,11 +115,15 @@ static void overlay_cache_init(void *vedata) /* Face Orientation Pass */ if (stl->g_data->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) { - int state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND; + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND; 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); } + if (stl->g_data->overlay.flag & V3D_OVERLAY_WIREFRAMES) { + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND; + psl->face_wireframe_pass = DRW_pass_create("Face Wires", state); + } } static void overlay_cache_populate(void *vedata, Object *ob) @@ -111,17 +131,41 @@ 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; + OVERLAY_PassList *psl = data->psl; + const DRWContextState *draw_ctx = DRW_context_state_get(); if (!DRW_object_is_renderable(ob)) return; - struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); - if (geom) { - /* Face Orientation */ - if (stl->g_data->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) { + if (stl->g_data->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) { + struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); + if (geom) { DRW_shgroup_call_add(pd->face_orientation_shgrp, geom, ob->obmat); } } + + if (stl->g_data->overlay.flag & V3D_OVERLAY_WIREFRAMES) { + /* Don't do that in edit mode. */ + if ((ob != draw_ctx->object_edit) && !BKE_object_is_in_editmode(ob)) { + int tri_count; + GPUTexture *verts = NULL, *faceids; + DRW_cache_object_face_wireframe_get(ob, &verts, &faceids, &tri_count); + if (verts) { + float *rim_col = ts.colorWire; + if ((ob->base_flag & BASE_SELECTED) != 0) { + rim_col = (ob == draw_ctx->obact) ? ts.colorActive : ts.colorSelect; + } + /* TODO(fclem): Compare performance with a geom shader based approach. */ + DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.face_wireframe_sh, psl->face_wireframe_pass); + DRW_shgroup_uniform_texture(shgrp, "vertData", verts); + DRW_shgroup_uniform_texture(shgrp, "faceIds", faceids); + DRW_shgroup_uniform_vec3(shgrp, "wireColor", ts.colorWire, 1); + DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1); + DRW_shgroup_uniform_vec2(shgrp, "viewportSize", DRW_viewport_size_get(), 1); + DRW_shgroup_call_procedural_triangles_add(shgrp, tri_count, ob->obmat); + } + } + } } static void overlay_cache_finish(void *UNUSED(vedata)) @@ -138,11 +182,15 @@ static void overlay_draw_scene(void *vedata) if (pd->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) { DRW_draw_pass(psl->face_orientation_pass); } + if (pd->overlay.flag & V3D_OVERLAY_WIREFRAMES) { + DRW_draw_pass(psl->face_wireframe_pass); + } } static void overlay_engine_free(void) { DRW_SHADER_FREE_SAFE(e_data.face_orientation_sh); + DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sh); } static const DrawEngineDataSize overlay_data_size = DRW_VIEWPORT_DATA_SIZE(OVERLAY_Data); |