diff options
Diffstat (limited to 'source/blender/draw/modes/overlay_mode.c')
-rw-r--r-- | source/blender/draw/modes/overlay_mode.c | 533 |
1 files changed, 0 insertions, 533 deletions
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c deleted file mode 100644 index 9106e89663d..00000000000 --- a/source/blender/draw/modes/overlay_mode.c +++ /dev/null @@ -1,533 +0,0 @@ -/* - * 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. - * - * Copyright 2016, Blender Foundation. - */ - -/** \file - * \ingroup draw_engine - */ - -#include "DNA_mesh_types.h" -#include "DNA_view3d_types.h" - -#include "BKE_editmesh.h" -#include "BKE_global.h" -#include "BKE_object.h" -#include "BKE_paint.h" - -#include "BLI_hash.h" - -#include "GPU_shader.h" -#include "DRW_render.h" - -#include "ED_view3d.h" - -#include "draw_mode_engines.h" - -#ifdef __APPLE__ -# define USE_GEOM_SHADER_WORKAROUND 1 -#else -# define USE_GEOM_SHADER_WORKAROUND 0 -#endif - -/* Structures */ - -typedef struct OVERLAY_DupliData { - DRWShadingGroup *shgrp; - struct GPUBatch *geom; - short base_flag; -} OVERLAY_DupliData; - -typedef struct OVERLAY_StorageList { - struct OVERLAY_PrivateData *g_data; -} 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 { - void *engine_type; - DRWViewportEmptyList *fbl; - DRWViewportEmptyList *txl; - OVERLAY_PassList *psl; - OVERLAY_StorageList *stl; -} OVERLAY_Data; - -typedef struct OVERLAY_PrivateData { - DRWShadingGroup *face_orientation_shgrp; - DRWShadingGroup *face_wires_shgrp; - DRWShadingGroup *face_wires_xray_shgrp; - DRWView *view_wires; - View3DOverlay overlay; - float wire_step_param; - bool clear_stencil; - bool show_overlays; -} OVERLAY_PrivateData; /* Transient data */ - -typedef struct OVERLAY_Shaders { - /* Face orientation shader */ - struct GPUShader *face_orientation; - /* Wireframe shader */ - struct GPUShader *select_wireframe; - struct GPUShader *face_wireframe; -} OVERLAY_Shaders; - -/* *********** STATIC *********** */ -static struct { - OVERLAY_Shaders sh_data[GPU_SHADER_CFG_LEN]; -} 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_geom_glsl[]; -extern char datatoc_overlay_face_wireframe_frag_glsl[]; -extern char datatoc_gpu_shader_depth_only_frag_glsl[]; - -extern char datatoc_common_view_lib_glsl[]; - -/* Functions */ -static void overlay_engine_init(void *vedata) -{ - OVERLAY_Data *data = vedata; - OVERLAY_StorageList *stl = data->stl; - - const DRWContextState *draw_ctx = DRW_context_state_get(); - OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; - - if (!stl->g_data) { - /* Alloc transient pointers */ - stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__); - } - - 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]; - - if (!sh_data->face_orientation) { - /* Face orientation */ - sh_data->face_orientation = GPU_shader_create_from_arrays({ - .vert = (const char *[]){sh_cfg_data->lib, - datatoc_common_view_lib_glsl, - datatoc_overlay_face_orientation_vert_glsl, - NULL}, - .frag = (const char *[]){datatoc_overlay_face_orientation_frag_glsl, NULL}, - .defs = (const char *[]){sh_cfg_data->def, NULL}, - }); - } - - if (!sh_data->face_wireframe) { - sh_data->select_wireframe = GPU_shader_create_from_arrays({ - .vert = (const char *[]){sh_cfg_data->lib, - datatoc_common_view_lib_glsl, - datatoc_overlay_face_wireframe_vert_glsl, - NULL}, - .geom = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_geom_glsl, NULL}, - .frag = (const char *[]){datatoc_gpu_shader_depth_only_frag_glsl, NULL}, - .defs = (const char *[]){sh_cfg_data->def, "#define SELECT_EDGES\n", NULL}, - }); -#if USE_GEOM_SHADER_WORKAROUND - /* Apple drivers does not support wide wires. Use geometry shader as a workaround. */ - sh_data->face_wireframe = GPU_shader_create_from_arrays({ - .vert = (const char *[]){sh_cfg_data->lib, - datatoc_common_view_lib_glsl, - datatoc_overlay_face_wireframe_vert_glsl, - NULL}, - .geom = (const char *[]){sh_cfg_data->lib, datatoc_overlay_face_wireframe_geom_glsl, NULL}, - .frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL}, - .defs = (const char *[]){sh_cfg_data->def, "#define USE_GEOM\n", NULL}, - }); -#else - sh_data->face_wireframe = GPU_shader_create_from_arrays({ - .vert = (const char *[]){sh_cfg_data->lib, - datatoc_common_view_lib_glsl, - datatoc_overlay_face_wireframe_vert_glsl, - NULL}, - .frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL}, - .defs = (const char *[]){sh_cfg_data->def, NULL}, - }); -#endif - } - - 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; - OVERLAY_PassList *psl = data->psl; - OVERLAY_StorageList *stl = data->stl; - OVERLAY_PrivateData *g_data = stl->g_data; - - const DRWContextState *draw_ctx = DRW_context_state_get(); - RegionView3D *rv3d = draw_ctx->rv3d; - View3D *v3d = draw_ctx->v3d; - OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; - - if (v3d) { - g_data->overlay = v3d->overlay; - g_data->show_overlays = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0; - } - else { - memset(&g_data->overlay, 0, sizeof(g_data->overlay)); - g_data->show_overlays = false; - } - - if (g_data->show_overlays == false) { - g_data->overlay.flag = 0; - } - - if (v3d->shading.type == OB_WIRE) { - g_data->overlay.flag |= V3D_OVERLAY_WIREFRAMES; - } - - { - /* Face Orientation Pass */ - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA; - psl->face_orientation_pass = DRW_pass_create("Face Orientation", state); - g_data->face_orientation_shgrp = DRW_shgroup_create(sh_data->face_orientation, - psl->face_orientation_pass); - if (rv3d->rflag & RV3D_CLIPPING) { - DRW_shgroup_state_enable(g_data->face_orientation_shgrp, DRW_STATE_CLIP_PLANES); - } - } - - { - /* Wireframe */ - 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; - - 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); - - 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) { - geometry_shader_uniforms(g_data->face_wires_shgrp); - geometry_shader_uniforms(g_data->face_wires_xray_shgrp); - } - g_data->wire_step_param = stl->g_data->overlay.wireframe_threshold - 254.0f / 255.0f; - } -} - -static void overlay_wire_color_get(const View3D *v3d, - const Object *ob, - const bool use_coloring, - float **rim_col, - float **wire_col) -{ -#ifndef NDEBUG - *rim_col = NULL; - *wire_col = NULL; -#endif - const DRWContextState *draw_ctx = DRW_context_state_get(); - - if (UNLIKELY(ob->base_flag & BASE_FROM_SET)) { - *rim_col = G_draw.block.colorDupli; - *wire_col = G_draw.block.colorDupli; - } - else if (UNLIKELY(ob->base_flag & BASE_FROM_DUPLI)) { - if (ob->base_flag & BASE_SELECTED) { - if (G.moving & G_TRANSFORM_OBJ) { - *rim_col = G_draw.block.colorTransform; - } - else { - *rim_col = G_draw.block.colorDupliSelect; - } - } - else { - *rim_col = G_draw.block.colorDupli; - } - *wire_col = G_draw.block.colorDupli; - } - else if ((ob->base_flag & BASE_SELECTED) && use_coloring) { - if (G.moving & G_TRANSFORM_OBJ) { - *rim_col = G_draw.block.colorTransform; - } - else if (ob == draw_ctx->obact) { - *rim_col = G_draw.block.colorActive; - } - else { - *rim_col = G_draw.block.colorSelect; - } - *wire_col = G_draw.block.colorWire; - } - else { - *rim_col = G_draw.block.colorWire; - *wire_col = G_draw.block.colorBackground; - } - - if (v3d->shading.type == OB_WIRE) { - if (ELEM(v3d->shading.wire_color_type, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_RANDOM_COLOR)) { - /* Theses stays valid until next call. So we need to copy them when using them as uniform. */ - static float wire_col_val[3], rim_col_val[3]; - *wire_col = wire_col_val; - *rim_col = rim_col_val; - - if (v3d->shading.wire_color_type == V3D_SHADING_OBJECT_COLOR) { - linearrgb_to_srgb_v3_v3(*wire_col, ob->color); - mul_v3_fl(*wire_col, 0.5f); - copy_v3_v3(*rim_col, *wire_col); - } - else { - uint hash = BLI_ghashutil_strhash_p_murmur(ob->id.name); - if (ob->id.lib) { - hash = (hash * 13) ^ BLI_ghashutil_strhash_p_murmur(ob->id.lib->name); - } - - float hue = BLI_hash_int_01(hash); - float hsv[3] = {hue, 0.75f, 0.8f}; - hsv_to_rgb_v(hsv, *wire_col); - copy_v3_v3(*rim_col, *wire_col); - } - - if ((ob->base_flag & BASE_SELECTED) && use_coloring) { - /* "Normalize" color. */ - add_v3_fl(*wire_col, 1e-4f); - float brightness = max_fff((*wire_col)[0], (*wire_col)[1], (*wire_col)[2]); - mul_v3_fl(*wire_col, (0.5f / brightness)); - add_v3_fl(*rim_col, 0.75f); - } - else { - mul_v3_fl(*rim_col, 0.5f); - add_v3_fl(*wire_col, 0.5f); - } - } - } - BLI_assert(*rim_col && *wire_col); -} - -static void overlay_cache_populate(void *vedata, Object *ob) -{ - OVERLAY_Data *data = vedata; - OVERLAY_StorageList *stl = data->stl; - OVERLAY_PrivateData *pd = stl->g_data; - const DRWContextState *draw_ctx = DRW_context_state_get(); - View3D *v3d = draw_ctx->v3d; - - if ((ob->dt < OB_WIRE) || (!DRW_object_is_renderable(ob) && (ob->dt != OB_WIRE))) { - return; - } - - if (DRW_object_is_renderable(ob) && pd->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) { - struct GPUBatch *geom = DRW_cache_object_surface_get(ob); - if (geom) { - DRW_shgroup_call(pd->face_orientation_shgrp, geom, ob); - } - } - - if ((pd->overlay.flag & V3D_OVERLAY_WIREFRAMES) || (v3d->shading.type == OB_WIRE) || - (ob->dtx & OB_DRAWWIRE) || (ob->dt == OB_WIRE)) { - - /* Fast path for duplis. */ - OVERLAY_DupliData **dupli_data = (OVERLAY_DupliData **)DRW_duplidata_get(vedata); - if (dupli_data) { - if (*dupli_data == NULL) { - *dupli_data = MEM_callocN(sizeof(OVERLAY_DupliData), "OVERLAY_DupliData"); - } - else { - if ((*dupli_data)->shgrp && (*dupli_data)->geom) { - if ((*dupli_data)->base_flag == ob->base_flag) { - DRW_shgroup_call((*dupli_data)->shgrp, (*dupli_data)->geom, ob); - } - else { - /* Continue and create a new Shgroup. */ - } - } - else { - return; - } - } - } - - const bool is_edit_mode = BKE_object_is_in_editmode(ob); - bool has_edit_mesh_cage = false; - if (ob->type == OB_MESH) { - /* TODO: Should be its own function. */ - Mesh *me = (Mesh *)ob->data; - BMEditMesh *embm = me->edit_mesh; - if (embm) { - has_edit_mesh_cage = embm->mesh_eval_cage && - (embm->mesh_eval_cage != embm->mesh_eval_final); - } - } - - /* Don't do that in edit Mesh mode, unless there is a modifier preview. */ - if ((!pd->show_overlays) || - (((ob != draw_ctx->object_edit) && !is_edit_mode) || has_edit_mesh_cage) || - ob->type != OB_MESH) { - const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) && - !DRW_state_is_image_render(); - 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); - DRWShadingGroup *shgrp = NULL; - - struct GPUBatch *geom; - geom = DRW_cache_object_face_wireframe_get(ob); - - if (geom || use_sculpt_pbvh) { - 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); - } - - if (draw_ctx->rv3d->rflag & RV3D_CLIPPING) { - DRW_shgroup_state_enable(shgrp, DRW_STATE_CLIP_PLANES); - } - - float wire_step_param = 10.0f; - if (!use_sculpt_pbvh) { - wire_step_param = (all_wires) ? 1.0f : pd->wire_step_param; - } - DRW_shgroup_uniform_float_copy(shgrp, "wireStepParam", wire_step_param); - - if (!(DRW_state_is_select() || DRW_state_is_depth())) { - float *rim_col, *wire_col; - overlay_wire_color_get(v3d, ob, use_coloring, &rim_col, &wire_col); - DRW_shgroup_uniform_vec3_copy(shgrp, "wireColor", wire_col); - DRW_shgroup_uniform_vec3_copy(shgrp, "rimColor", rim_col); - DRW_shgroup_stencil_mask(shgrp, - (is_xray && (is_wire || !pd->clear_stencil)) ? 0x00 : 0xFF); - } - - if (use_sculpt_pbvh) { - DRW_shgroup_call_sculpt(shgrp, ob, true, false, false); - } - else { - DRW_shgroup_call(shgrp, geom, ob); - } - } - - if (dupli_data) { - (*dupli_data)->shgrp = shgrp; - (*dupli_data)->geom = geom; - (*dupli_data)->base_flag = ob->base_flag; - } - } - } -} - -static void overlay_draw_scene(void *vedata) -{ - OVERLAY_Data *data = vedata; - OVERLAY_PassList *psl = data->psl; - OVERLAY_StorageList *stl = data->stl; - DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); - DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - - 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); - - if (dfbl->multisample_fb != NULL && DRW_state_is_fbo()) { - DRW_stats_query_start("Multisample Blit"); - GPU_framebuffer_bind(dfbl->multisample_fb); - GPU_framebuffer_clear_color(dfbl->multisample_fb, (const float[4]){0.0f}); - /* Special blit: we need the original depth and stencil - * in the Multisample buffer. */ - 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); - - /* TODO(fclem): find a way to unify the multisample pass together - * (non meshes + armature + wireframe) */ - MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl); -} - -static void overlay_engine_free(void) -{ - for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) { - OVERLAY_Shaders *sh_data = &e_data.sh_data[sh_data_index]; - GPUShader **sh_data_as_array = (GPUShader **)sh_data; - for (int i = 0; i < (sizeof(OVERLAY_Shaders) / sizeof(GPUShader *)); i++) { - DRW_SHADER_FREE_SAFE(sh_data_as_array[i]); - } - } -} - -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, - NULL, - NULL, - &overlay_draw_scene, - NULL, - NULL, - NULL, -}; |