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>2019-06-24 13:42:04 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-06-26 13:03:59 +0300
commite47ce1f2d6d7df814bd6498ae7b881989510395f (patch)
treee7350615fc161f76fc6452644eeccf90571788a5 /source/blender/draw/modes/overlay_mode.c
parentbf1b00212ac1129eb72d8dc2cb741eb04fcf6dcf (diff)
Fix T65755 "In Front" (X-Ray) doesn't work with wire objects
We fix by separating the drawing of wire xray objects. These wire objects gets drawn before normal wires and set the stencil to 0x0 just like the solid counterparts. Also a prepass is done to "dig" through non-xray solid.
Diffstat (limited to 'source/blender/draw/modes/overlay_mode.c')
-rw-r--r--source/blender/draw/modes/overlay_mode.c110
1 files changed, 59 insertions, 51 deletions
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index aaaeefa81c9..ae5c0064cde 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -59,6 +59,8 @@ typedef struct OVERLAY_StorageList {
typedef struct OVERLAY_PassList {
struct DRWPass *face_orientation_pass;
struct DRWPass *face_wireframe_pass;
+ struct DRWPass *face_wireframe_only_pass;
+ struct DRWPass *face_wireframe_xray_pass;
} OVERLAY_PassList;
typedef struct OVERLAY_Data {
@@ -72,11 +74,12 @@ typedef struct OVERLAY_Data {
typedef struct OVERLAY_PrivateData {
DRWShadingGroup *face_orientation_shgrp;
DRWShadingGroup *face_wires_shgrp;
+ DRWShadingGroup *face_wires_xray_shgrp;
DRWView *view_wires;
BLI_mempool *wire_color_mempool;
View3DOverlay overlay;
float wire_step_param;
- bool ghost_stencil_test;
+ bool clear_stencil;
bool show_overlays;
} OVERLAY_PrivateData; /* Transient data */
@@ -117,7 +120,8 @@ static void overlay_engine_init(void *vedata)
/* Alloc transient pointers */
stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
}
- stl->g_data->ghost_stencil_test = false;
+
+ stl->g_data->clear_stencil = (draw_ctx->v3d->shading.type > OB_SOLID);
const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
@@ -169,6 +173,13 @@ static void overlay_engine_init(void *vedata)
stl->g_data->view_wires = DRW_view_create_with_zoffset(draw_ctx->rv3d, 0.5f);
}
+static void geometry_shader_uniforms(DRWShadingGroup *shgrp)
+{
+ DRW_shgroup_uniform_float_copy(shgrp, "wireSize", U.pixelsize * 0.5f);
+ DRW_shgroup_uniform_vec2(shgrp, "viewportSize", DRW_viewport_size_get(), 1);
+ DRW_shgroup_uniform_vec2(shgrp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
+}
+
static void overlay_cache_init(void *vedata)
{
OVERLAY_Data *data = vedata;
@@ -215,27 +226,28 @@ static void overlay_cache_init(void *vedata)
{
/* Wireframe */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS |
- DRW_STATE_FIRST_VERTEX_CONVENTION;
- float wire_size = U.pixelsize * 0.5f;
-
const bool use_select = (DRW_state_is_select() || DRW_state_is_depth());
GPUShader *face_wires_sh = use_select ? sh_data->select_wireframe : sh_data->face_wireframe;
- psl->face_wireframe_pass = DRW_pass_create("Face Wires", state);
-
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
+ DRW_STATE_STENCIL_EQUAL | DRW_STATE_FIRST_VERTEX_CONVENTION;
+ psl->face_wireframe_pass = DRW_pass_create("Wires", state);
g_data->face_wires_shgrp = DRW_shgroup_create(face_wires_sh, psl->face_wireframe_pass);
- DRW_shgroup_uniform_float(
- g_data->face_wires_shgrp, "wireStepParam", &g_data->wire_step_param, 1);
+
+ DRWState state_xray = DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_STENCIL |
+ DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_STENCIL_NEQUAL |
+ DRW_STATE_FIRST_VERTEX_CONVENTION;
+ psl->face_wireframe_xray_pass = DRW_pass_create("Wires Only Xray", state_xray);
+ g_data->face_wires_xray_shgrp = DRW_shgroup_create(face_wires_sh,
+ psl->face_wireframe_xray_pass);
+
if (use_select || USE_GEOM_SHADER_WORKAROUND) {
- DRW_shgroup_uniform_float_copy(g_data->face_wires_shgrp, "wireSize", wire_size);
- DRW_shgroup_uniform_vec2(
- g_data->face_wires_shgrp, "viewportSize", DRW_viewport_size_get(), 1);
- DRW_shgroup_uniform_vec2(
- g_data->face_wires_shgrp, "viewportSizeInv", DRW_viewport_invert_size_get(), 1);
+ geometry_shader_uniforms(g_data->face_wires_shgrp);
+ geometry_shader_uniforms(g_data->face_wires_xray_shgrp);
}
if (rv3d->rflag & RV3D_CLIPPING) {
DRW_shgroup_state_enable(g_data->face_wires_shgrp, DRW_STATE_CLIP_PLANES);
+ DRW_shgroup_state_enable(g_data->face_wires_xray_shgrp, DRW_STATE_CLIP_PLANES);
}
g_data->wire_step_param = stl->g_data->overlay.wireframe_threshold - 254.0f / 255.0f;
@@ -383,19 +395,21 @@ static void overlay_cache_populate(void *vedata, Object *ob)
const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d);
const bool all_wires = (ob->dtx & OB_DRAW_ALL_EDGES);
const bool is_wire = (ob->dt < OB_SOLID);
+ const bool is_xray = (ob->dtx & OB_DRAWXRAY);
const bool use_coloring = (pd->show_overlays && !is_edit_mode && !use_sculpt_pbvh &&
!has_edit_mesh_cage);
- const int stencil_mask = (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF;
- float *rim_col, *wire_col;
DRWShadingGroup *shgrp = NULL;
- overlay_wire_color_get(v3d, pd, ob, use_coloring, &rim_col, &wire_col);
-
struct GPUBatch *geom;
geom = DRW_cache_object_face_wireframe_get(ob);
if (geom || use_sculpt_pbvh) {
- shgrp = DRW_shgroup_create_sub(pd->face_wires_shgrp);
+ if (is_wire && is_xray) {
+ shgrp = DRW_shgroup_create_sub(pd->face_wires_xray_shgrp);
+ }
+ else {
+ shgrp = DRW_shgroup_create_sub(pd->face_wires_shgrp);
+ }
float wire_step_param = 10.0f;
if (!use_sculpt_pbvh) {
@@ -404,9 +418,12 @@ static void overlay_cache_populate(void *vedata, Object *ob)
DRW_shgroup_uniform_float_copy(shgrp, "wireStepParam", wire_step_param);
if (!(DRW_state_is_select() || DRW_state_is_depth())) {
- DRW_shgroup_stencil_mask(shgrp, stencil_mask);
+ float *rim_col, *wire_col;
+ overlay_wire_color_get(v3d, pd, ob, use_coloring, &rim_col, &wire_col);
DRW_shgroup_uniform_vec3(shgrp, "wireColor", wire_col, 1);
DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
+ DRW_shgroup_stencil_mask(shgrp,
+ (is_xray && (is_wire || !pd->clear_stencil)) ? 0x00 : 0xFF);
}
if (use_sculpt_pbvh) {
@@ -421,35 +438,6 @@ static void overlay_cache_populate(void *vedata, Object *ob)
(*dupli_data)->shgrp = shgrp;
(*dupli_data)->geom = geom;
}
-
- if (is_wire && shgrp != NULL) {
- /* If object is wireframe, don't try to use stencil test. */
- DRW_shgroup_state_disable(shgrp, DRW_STATE_STENCIL_EQUAL);
-
- if (ob->dtx & OB_DRAWXRAY) {
- DRW_shgroup_state_disable(shgrp, DRW_STATE_DEPTH_LESS_EQUAL);
- }
- }
- else if ((ob->dtx & OB_DRAWXRAY) && shgrp != NULL) {
- pd->ghost_stencil_test = true;
- }
- }
- }
-}
-
-static void overlay_cache_finish(void *vedata)
-{
- OVERLAY_Data *data = vedata;
- OVERLAY_PassList *psl = data->psl;
- OVERLAY_StorageList *stl = data->stl;
-
- const DRWContextState *ctx = DRW_context_state_get();
- View3D *v3d = ctx->v3d;
-
- /* only in solid mode */
- if (v3d->shading.type == OB_SOLID && !XRAY_FLAG_ENABLED(v3d)) {
- if (stl->g_data->ghost_stencil_test) {
- DRW_pass_state_add(psl->face_wireframe_pass, DRW_STATE_STENCIL_EQUAL);
}
}
}
@@ -464,9 +452,18 @@ static void overlay_draw_scene(void *vedata)
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(dfbl->default_fb);
+
+ /* In material/rendered mode, Stencil has not be rendered correctly.
+ * Clear it to avoid problems.*/
+ if (stl->g_data->clear_stencil) {
+ GPU_framebuffer_clear_stencil(dfbl->default_fb, 0xFF);
+ }
}
DRW_draw_pass(psl->face_orientation_pass);
+ /* Do a depth prepass to lower the depth where the xray wire objects can pass through */
+ DRW_draw_pass(psl->face_wireframe_xray_pass);
+
/* This is replaced by the next code block */
// MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl);
@@ -479,9 +476,20 @@ static void overlay_draw_scene(void *vedata)
GPU_framebuffer_blit(
dfbl->default_fb, 0, dfbl->multisample_fb, 0, GPU_DEPTH_BIT | GPU_STENCIL_BIT);
DRW_stats_query_end();
+
+ /* Redo the prepass so we ge nice AA lines. */
+ DRW_draw_pass(psl->face_wireframe_xray_pass);
}
DRW_view_set_active(stl->g_data->view_wires);
+
+ DRW_pass_state_remove(psl->face_wireframe_xray_pass,
+ DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_STENCIL_NEQUAL);
+ DRW_pass_state_add(psl->face_wireframe_xray_pass,
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL |
+ DRW_STATE_STENCIL_ALWAYS);
+ DRW_draw_pass(psl->face_wireframe_xray_pass);
+
DRW_draw_pass(psl->face_wireframe_pass);
DRW_view_set_active(NULL);
@@ -519,7 +527,7 @@ DrawEngineType draw_engine_overlay_type = {
&overlay_engine_free,
&overlay_cache_init,
&overlay_cache_populate,
- &overlay_cache_finish,
+ NULL,
NULL,
&overlay_draw_scene,
NULL,