Cleanup: remove redundant doxygen \file argument
[blender.git] / source / blender / draw / modes / overlay_mode.c
index e5b7959..b026bb5 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * 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
  * 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
- *
+ * Copyright 2016, Blender Foundation.
  */
 
-/** \file overlay_mode.c
- *  \ingroup draw_engine
+/** \file \ingroup draw_engine
  */
 
 #include "DNA_mesh_types.h"
 #include "BKE_global.h"
 
 #include "GPU_shader.h"
-#include "GPU_extensions.h"
 #include "DRW_render.h"
 
-#include "draw_mode_engines.h"
 
 /* Structures */
 typedef struct OVERLAY_StorageList {
@@ -56,25 +50,31 @@ typedef struct OVERLAY_Data {
 
 typedef struct OVERLAY_PrivateData {
        DRWShadingGroup *face_orientation_shgrp;
-       DRWShadingGroup *face_wires;
-       DRWShadingGroup *flat_wires;
-       DRWShadingGroup *sculpt_wires;
+       DRWShadingGroup *face_wires_shgrp;
+       DRWShadingGroup *flat_wires_shgrp;
+       DRWShadingGroup *sculpt_wires_shgrp;
        View3DOverlay overlay;
        float wire_step_param[2];
        bool ghost_stencil_test;
        bool show_overlays;
 } OVERLAY_PrivateData; /* Transient data */
 
-/* *********** STATIC *********** */
-static struct {
+typedef struct OVERLAY_Shaders {
        /* Face orientation shader */
-       struct GPUShader *face_orientation_sh;
+       struct GPUShader *face_orientation;
        /* Wireframe shader */
-       struct GPUShader *select_wireframe_sh;
-       struct GPUShader *face_wireframe_sh;
-       struct GPUShader *face_wireframe_sculpt_sh;
+       struct GPUShader *select_wireframe;
+       struct GPUShader *face_wireframe;
+       struct GPUShader *face_wireframe_sculpt;
+} OVERLAY_Shaders;
+
+/* *********** STATIC *********** */
+static struct {
+       OVERLAY_Shaders sh_data[GPU_SHADER_CFG_LEN];
 } e_data = {NULL};
 
+extern char datatoc_gpu_shader_cfg_world_clip_lib_glsl[];
+
 /* Shaders */
 extern char datatoc_overlay_face_orientation_frag_glsl[];
 extern char datatoc_overlay_face_orientation_vert_glsl[];
@@ -84,45 +84,56 @@ 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 struct GlobalsUboStorage ts; /* draw_common.c */
-
 /* 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->shader_cfg];
+       const bool is_clip = (draw_ctx->rv3d->rflag & RV3D_CLIPPING) != 0;
+
+       if (is_clip) {
+               DRW_state_clip_planes_set_from_rv3d(draw_ctx->rv3d);
+       }
+
        if (!stl->g_data) {
                /* Alloc transient pointers */
                stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
        }
        stl->g_data->ghost_stencil_test = false;
 
-       if (!e_data.face_orientation_sh) {
+       const char *world_clip_lib_or_empty = is_clip ? datatoc_gpu_shader_cfg_world_clip_lib_glsl : "";
+       const char *world_clip_def_or_empty = is_clip ? "#define USE_WORLD_CLIP_PLANES\n" : "";
+
+       if (!sh_data->face_orientation) {
                /* Face orientation */
-               e_data.face_orientation_sh = DRW_shader_create(
-                       datatoc_overlay_face_orientation_vert_glsl, NULL,
-                       datatoc_overlay_face_orientation_frag_glsl, NULL);
+               sh_data->face_orientation = GPU_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_orientation_vert_glsl, NULL},
+                       .frag = (const char *[]){datatoc_overlay_face_orientation_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, NULL},
+               });
        }
 
-       if (!e_data.face_wireframe_sh) {
-               e_data.select_wireframe_sh = DRW_shader_create(
-                       datatoc_overlay_face_wireframe_vert_glsl,
-                       datatoc_overlay_face_wireframe_geom_glsl,
-                       datatoc_gpu_shader_depth_only_frag_glsl,
-                       "#define SELECT_EDGES\n");
-
-               e_data.face_wireframe_sh = DRW_shader_create(
-                       datatoc_overlay_face_wireframe_vert_glsl,
-                       NULL,
-                       datatoc_overlay_face_wireframe_frag_glsl,
-                       NULL);
-
-               e_data.face_wireframe_sculpt_sh = DRW_shader_create(
-                       datatoc_overlay_face_wireframe_vert_glsl,
-                       datatoc_overlay_face_wireframe_geom_glsl,
-                       datatoc_overlay_face_wireframe_frag_glsl,
-                       "#define USE_SCULPT\n");
+       if (!sh_data->face_wireframe) {
+               sh_data->select_wireframe = GPU_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_wireframe_vert_glsl, NULL},
+                       .geom = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_wireframe_geom_glsl, NULL},
+                       .frag = (const char *[]){datatoc_gpu_shader_depth_only_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, "#define SELECT_EDGES\n", NULL},
+               });
+               sh_data->face_wireframe = GPU_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_wireframe_vert_glsl, NULL},
+                       .frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, NULL},
+               });
+               sh_data->face_wireframe_sculpt = GPU_shader_create_from_arrays({
+                       .vert = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_wireframe_vert_glsl, NULL},
+                       .geom = (const char *[]){world_clip_lib_or_empty, datatoc_overlay_face_wireframe_geom_glsl, NULL},
+                       .frag = (const char *[]){datatoc_overlay_face_wireframe_frag_glsl, NULL},
+                       .defs = (const char *[]){world_clip_def_or_empty, "#define USE_SCULPT\n", NULL},
+               });
        }
 }
 
@@ -133,6 +144,10 @@ static void overlay_cache_init(void *vedata)
        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;
+       OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->shader_cfg];
+
        const DRWContextState *DCS = DRW_context_state_get();
 
        View3D *v3d = DCS->v3d;
@@ -159,7 +174,10 @@ static void overlay_cache_init(void *vedata)
                DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND;
                psl->face_orientation_pass = DRW_pass_create("Face Orientation", state);
                g_data->face_orientation_shgrp = DRW_shgroup_create(
-                       e_data.face_orientation_sh, psl->face_orientation_pass);
+                       sh_data->face_orientation, psl->face_orientation_pass);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(g_data->face_orientation_shgrp, rv3d);
+               }
        }
 
        {
@@ -168,22 +186,31 @@ static void overlay_cache_init(void *vedata)
                float wire_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
 
                const bool use_select = (DRW_state_is_select() || DRW_state_is_depth());
-               GPUShader *sculpt_wire_sh = use_select ? e_data.select_wireframe_sh : e_data.face_wireframe_sculpt_sh;
-               GPUShader *face_wires_sh = use_select ? e_data.select_wireframe_sh : e_data.face_wireframe_sh;
+               GPUShader *sculpt_wire_sh = use_select ? sh_data->select_wireframe : sh_data->face_wireframe_sculpt;
+               GPUShader *face_wires_sh = use_select ? sh_data->select_wireframe : sh_data->face_wireframe;
                GPUShader *flat_wires_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
 
                psl->face_wireframe_pass = DRW_pass_create("Face Wires", state);
 
-               g_data->flat_wires = DRW_shgroup_create(flat_wires_sh, psl->face_wireframe_pass);
+               g_data->flat_wires_shgrp = DRW_shgroup_create(flat_wires_sh, psl->face_wireframe_pass);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(g_data->flat_wires_shgrp, rv3d);
+               }
 
-               g_data->sculpt_wires = DRW_shgroup_create(sculpt_wire_sh, psl->face_wireframe_pass);
+               g_data->sculpt_wires_shgrp = DRW_shgroup_create(sculpt_wire_sh, psl->face_wireframe_pass);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(g_data->sculpt_wires_shgrp, rv3d);
+               }
 
-               g_data->face_wires = DRW_shgroup_create(face_wires_sh, psl->face_wireframe_pass);
-               DRW_shgroup_uniform_vec2(g_data->face_wires, "wireStepParam", g_data->wire_step_param, 1);
+               g_data->face_wires_shgrp = DRW_shgroup_create(face_wires_sh, psl->face_wireframe_pass);
+               DRW_shgroup_uniform_vec2(g_data->face_wires_shgrp, "wireStepParam", g_data->wire_step_param, 1);
+               if (rv3d->rflag & RV3D_CLIPPING) {
+                       DRW_shgroup_world_clip_planes_from_rv3d(g_data->face_wires_shgrp, rv3d);
+               }
 
                if (!use_select) {
-                       DRW_shgroup_uniform_float_copy(g_data->sculpt_wires, "wireSize", wire_size);
-                       DRW_shgroup_uniform_float_copy(g_data->face_wires, "wireSize", wire_size);
+                       DRW_shgroup_uniform_float_copy(g_data->sculpt_wires_shgrp, "wireSize", wire_size);
+                       DRW_shgroup_uniform_float_copy(g_data->face_wires_shgrp, "wireSize", wire_size);
                }
 
                /* Control aspect of the falloff. */
@@ -192,6 +219,8 @@ static void overlay_cache_init(void *vedata)
                const float decompress = (0xFF / (float)(0xFF - 0x20));
                g_data->wire_step_param[0] = -sharpness * decompress;
                g_data->wire_step_param[1] = decompress + sharpness * stl->g_data->overlay.wireframe_threshold;
+
+
        }
 }
 
@@ -246,25 +275,58 @@ static void overlay_cache_populate(void *vedata, Object *ob)
                        const int stencil_mask = (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF;
                        DRWShadingGroup *shgrp = NULL;
 
-                       float *rim_col = ts.colorWire;
-                       if (!is_edit_mode && !is_sculpt_mode && !has_edit_mesh_cage &&
-                           ((ob->base_flag & BASE_SELECTED) != 0))
+                       const float *rim_col = NULL;
+                       const float *wire_col = NULL;
+                       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) &&
+                                (!is_edit_mode && !is_sculpt_mode && !has_edit_mesh_cage))
                        {
-                               rim_col = (ob == draw_ctx->obact) ? ts.colorActive : ts.colorSelect;
-                               rim_col = (G.moving & G_TRANSFORM_OBJ) ? ts.colorTransform : rim_col;
+                               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.colorWire;
+                       }
+                       BLI_assert(rim_col && wire_col);
 
                        /* This fixes only the biggest case which is a plane in ortho view. */
                        int flat_axis = 0;
-                       bool is_flat_object_viewed_from_side = (rv3d->persp == RV3D_ORTHO) &&
-                                                              DRW_object_is_flat(ob, &flat_axis) &&
-                                                              DRW_object_axis_orthogonal_to_view(ob, flat_axis);
+                       bool is_flat_object_viewed_from_side = (
+                               (rv3d->persp == RV3D_ORTHO) &&
+                               DRW_object_is_flat(ob, &flat_axis) &&
+                               DRW_object_axis_orthogonal_to_view(ob, flat_axis));
 
                        if (is_flat_object_viewed_from_side && !is_sculpt_mode) {
                                /* Avoid losing flat objects when in ortho views (see T56549) */
                                struct GPUBatch *geom = DRW_cache_object_all_edges_get(ob);
                                if (geom) {
-                                       shgrp = pd->flat_wires;
+                                       shgrp = pd->flat_wires_shgrp;
                                        shgrp = DRW_shgroup_create_sub(shgrp);
                                        DRW_shgroup_stencil_mask(shgrp, stencil_mask);
                                        DRW_shgroup_call_object_add(shgrp, geom, ob);
@@ -274,17 +336,17 @@ static void overlay_cache_populate(void *vedata, Object *ob)
                        else {
                                struct GPUBatch *geom = DRW_cache_object_face_wireframe_get(ob);
                                if (geom || is_sculpt_mode) {
-                                       shgrp = (is_sculpt_mode) ? pd->sculpt_wires : pd->face_wires;
+                                       shgrp = (is_sculpt_mode) ? pd->sculpt_wires_shgrp : pd->face_wires_shgrp;
                                        shgrp = DRW_shgroup_create_sub(shgrp);
 
                                        static float all_wires_params[2] = {0.0f, 10.0f}; /* Parameters for all wires */
-                                       DRW_shgroup_uniform_vec2(shgrp, "wireStepParam", (all_wires)
-                                                                                        ? all_wires_params
-                                                                                        : pd->wire_step_param, 1);
+                                       DRW_shgroup_uniform_vec2(
+                                               shgrp, "wireStepParam", (all_wires) ?
+                                               all_wires_params : pd->wire_step_param, 1);
 
                                        if (!(DRW_state_is_select() || DRW_state_is_depth())) {
                                                DRW_shgroup_stencil_mask(shgrp, stencil_mask);
-                                               DRW_shgroup_uniform_vec3(shgrp, "wireColor", ts.colorWire, 1);
+                                               DRW_shgroup_uniform_vec3(shgrp, "wireColor", wire_col, 1);
                                                DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
                                        }
 
@@ -343,10 +405,13 @@ static void overlay_draw_scene(void *vedata)
 
 static void overlay_engine_free(void)
 {
-       DRW_SHADER_FREE_SAFE(e_data.face_orientation_sh);
-       DRW_SHADER_FREE_SAFE(e_data.select_wireframe_sh);
-       DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sh);
-       DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sculpt_sh);
+       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);