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:
authorClément Foucault <foucault.clem@gmail.com>2018-05-31 20:01:22 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-05-31 20:09:20 +0300
commitbf4ce5755f3699105a1e97793db63f9fc8f7ad9a (patch)
treee9c6855b3305e26dd4def29cea78253e7b7fa507 /source/blender/draw/modes/overlay_mode.c
parent712885c30ef2a8dbde91b7d8b4ffb9784a70fca5 (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.c60
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);