diff options
Diffstat (limited to 'source/blender/draw/engines')
32 files changed, 849 insertions, 35 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 1b152afa3bf..93521c71127 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -47,7 +47,7 @@ static struct { struct GPUShader *downsample_sh; struct GPUShader *downsample_cube_sh; - /* Theses are just references, not actually allocated */ + /* These are just references, not actually allocated */ struct GPUTexture *depth_src; struct GPUTexture *color_src; diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index 3977fd160fc..c82a112b343 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -266,7 +266,8 @@ static bool EEVEE_lightcache_validate(const LightCache *light_cache, (irr_size[2] == light_cache->grid_tx.tex_size[2]) && (grid_len == light_cache->grid_len)) { int mip_len = (int)(floorf(log2f(cube_res)) - MIN_CUBE_LOD_LEVEL); if ((cube_res == light_cache->cube_tx.tex_size[0]) && - (cube_len == light_cache->cube_tx.tex_size[2]) && (mip_len == light_cache->mips_len)) { + (cube_len == light_cache->cube_tx.tex_size[2]) && (cube_len == light_cache->cube_len) && + (mip_len == light_cache->mips_len)) { return true; } } diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 5341661735f..2026b44fe87 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -1275,7 +1275,7 @@ void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *v /* Rendering happens here! */ eevee_lightbake_render_scene_to_planars(sldata, vedata); - /* Make sure no aditionnal visibility check runs after this. */ + /* Make sure no additional visibility check runs after this. */ pinfo->vis_data.collection = NULL; DRW_uniformbuffer_update(sldata->planar_ubo, &sldata->probes->planar_data); diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index f6e8cefd165..d23287264b3 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -1347,7 +1347,7 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRWView int saved_ray_type = sldata->common_data.ray_type; - /* TODO: make it optionnal if we don't draw shadows. */ + /* TODO: make it optional if we don't draw shadows. */ sldata->common_data.ray_type = EEVEE_RAY_SHADOW; DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data); diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index abd5bb82815..670201555bd 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -74,7 +74,7 @@ static void eevee_motion_blur_camera_get_matrix_at_time(Scene *scene, /* FIXME : This is a temporal solution that does not take care of parent animations */ /* Recalc Anim manually */ BKE_animsys_evaluate_animdata( - draw_ctx->depsgraph, scene, &camdata_cpy.id, camdata_cpy.adt, time, ADT_RECALC_ALL); + scene, &camdata_cpy.id, camdata_cpy.adt, time, ADT_RECALC_ALL, false); BKE_object_where_is_calc_time(draw_ctx->depsgraph, scene, &cam_cpy, time); /* Compute winmat */ diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index bd08a61e3b8..8aeddc72316 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -633,7 +633,7 @@ typedef struct EEVEE_EffectsInfo { struct GPUTexture *source_buffer; /* latest updated texture */ struct GPUFrameBuffer *target_buffer; /* next target to render to */ struct GPUTexture *final_tx; /* Final color to transform to display color space. */ - struct GPUFrameBuffer *final_fb; /* Framebuffer with final_tx as attachement. */ + struct GPUFrameBuffer *final_fb; /* Framebuffer with final_tx as attachment. */ } EEVEE_EffectsInfo; /* ***************** COMMON DATA **************** */ @@ -761,8 +761,8 @@ typedef struct EEVEE_ShadowCascadeData { float radius[MAX_CASCADE_NUM]; } EEVEE_ShadowCascadeData; -/* Theses are the structs stored inside Objects. - * It works with even if the object is in multiple layers +/* These are the structs stored inside Objects. + * It works even if the object is in multiple layers * because we don't get the same "Object *" for each layer. */ typedef struct EEVEE_LightEngineData { DrawData dd; diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index 286bcd8f738..ebd13ef1cf5 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -91,7 +91,7 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph * copy_v4_fl4(camtexcofac, 1.0f, 1.0f, 0.0f, 0.0f); } - /* XXX overiding viewport size. Simplify things but is not really 100% safe. */ + /* XXX overriding viewport size. Simplify things but is not really 100% safe. */ DRW_render_viewport_size_set((int[2]){size_orig[0] + g_data->overscan_pixels * 2.0f, size_orig[1] + g_data->overscan_pixels * 2.0f}); diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c index d53ed239f4e..3d1b64422a4 100644 --- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c +++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c @@ -44,7 +44,7 @@ static struct { /* Screen Space Reflection */ struct GPUShader *ssr_sh[SSR_MAX_SHADER]; - /* Theses are just references, not actually allocated */ + /* These are just references, not actually allocated */ struct GPUTexture *depth_src; struct GPUTexture *color_src; } e_data = {{NULL}}; /* Engine data */ diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index f85c30044a9..7fb5c25ffc6 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -554,7 +554,7 @@ void EEVEE_volumes_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) /* Final integration: We compute for each froxel the * amount of scattered light and extinction coef at this - * given depth. We use theses textures as double buffer + * given depth. We use these textures as double buffer * for the volumetric history. */ txl->volume_scatter_history = DRW_texture_create_3d( tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL); diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl index d8cec17af58..ca4940ceffb 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl @@ -121,7 +121,7 @@ void main(void) /* Circle Dof */ float dist = length(particlecoord); - /* Ouside of bokeh shape */ + /* Outside of bokeh shape */ if (dist > 1.0) { discard; } @@ -141,7 +141,7 @@ void main(void) * Giving us the new linear radius to the shape edge. */ dist /= r; - /* Ouside of bokeh shape */ + /* Outside of bokeh shape */ if (dist > 1.0) { discard; } diff --git a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl index ac6751fb5fb..428318e3c68 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl @@ -96,7 +96,7 @@ void main() FragColor = safe_color(color_history); /* There is some ghost issue if we use the alpha - * in the viewport. Overwritting alpha fixes it. */ + * in the viewport. Overwriting alpha fixes it. */ FragColor.a = color.a; } diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl index a70ac686efd..56c05e3c036 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl @@ -261,7 +261,7 @@ vec3 probe_evaluate_grid(GridData gd, vec3 W, vec3 N, vec3 localpos) float weight_accum = 0.0; vec3 irradiance_accum = vec3(0.0); - /* For each neighboor cells */ + /* For each neighbor cells */ for (int i = 0; i < 8; ++i) { ivec3 offset = ivec3(i, i >> 1, i >> 2) & ivec3(1); vec3 cell_cos = clamp(localpos_floored + vec3(offset), vec3(0.0), vec3(gd.g_resolution) - 1.0); diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl index 82581f2327b..14e0c947b47 100644 --- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl @@ -83,8 +83,8 @@ void prepare_raycast(vec3 ray_origin, ss_start.w = project_point(ProjectionMatrix, ray_origin).z; ss_end.w = project_point(ProjectionMatrix, ray_end).z; - /* XXX This is a hack a better method is welcome ! */ - /* We take the delta between the offseted depth and the depth and substract it from the ray + /* XXX This is a hack. A better method is welcome! */ + /* We take the delta between the offsetted depth and the depth and subtract it from the ray * depth. This will change the world space thickness appearance a bit but we can have negative * values without worries. We cannot do this in viewspace because of the perspective division. */ ss_start.w = 2.0 * ss_start.z - ss_start.w; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl index 54f7dc10222..5646c257562 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_copy_frag.glsl @@ -3,7 +3,7 @@ layout(std140) uniform shadow_render_block { - /* Use vectors to avoid alignement padding. */ + /* Use vectors to avoid alignment padding. */ ivec4 shadowSampleCount; vec4 shadowInvSampleCount; vec4 filterSize; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_process_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_process_geom.glsl index 131cecd5db6..591666560c4 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_process_geom.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_process_geom.glsl @@ -4,7 +4,7 @@ layout(triangle_strip, max_vertices = 3) out; layout(std140) uniform shadow_render_block { - /* Use vectors to avoid alignement padding. */ + /* Use vectors to avoid alignment padding. */ ivec4 shadowSampleCount; vec4 shadowInvSampleCount; vec4 filterSize; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_process_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_process_vert.glsl index 01e0db97482..95e6a48b81f 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_process_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_process_vert.glsl @@ -1,7 +1,7 @@ layout(std140) uniform shadow_render_block { - /* Use vectors to avoid alignement padding. */ + /* Use vectors to avoid alignment padding. */ ivec4 shadowSampleCount; vec4 shadowInvSampleCount; vec4 filterSize; diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl index e2982358e52..5c19ccd5ce1 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl @@ -1,7 +1,7 @@ layout(std140) uniform shadow_render_block { - /* Use vectors to avoid alignement padding. */ + /* Use vectors to avoid alignment padding. */ ivec4 shadowSampleCount; vec4 shadowInvSampleCount; vec4 filterSize; diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl index 4096fc2d511..2b1ae60654e 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl @@ -11,7 +11,7 @@ uniform vec3 volumeOrcoSize; flat in int slice; -/* Warning: theses are not attributes, theses are global vars. */ +/* Warning: these are not attributes, these are global vars. */ vec3 worldPosition = vec3(0.0); vec3 viewPosition = vec3(0.0); vec3 viewNormal = vec3(0.0); diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c index 18950f00823..d5f8d062593 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c @@ -375,7 +375,7 @@ GPUBatch *gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness) Object *ob = draw_ctx->obact; tGPspoint *points = gpd->runtime.sbuffer; - int totpoints = gpd->runtime.sbuffer_size; + int totpoints = gpd->runtime.sbuffer_used; /* if cyclic needs more vertex */ int cyclic_add = (gpd->runtime.sbuffer_sflag & GP_STROKE_CYCLIC) ? 1 : 0; int totvertex = totpoints + cyclic_add + 2; @@ -477,7 +477,7 @@ GPUBatch *gpencil_get_buffer_point_geom(bGPdata *gpd, short thickness) Object *ob = draw_ctx->obact; tGPspoint *points = gpd->runtime.sbuffer; - int totpoints = gpd->runtime.sbuffer_size; + int totpoints = gpd->runtime.sbuffer_used; static GPUVertFormat format = {0}; static uint pos_id, color_id, thickness_id, uvdata_id, prev_pos_id; @@ -621,7 +621,7 @@ GPUBatch *gpencil_get_buffer_fill_geom(bGPdata *gpd) } const tGPspoint *points = gpd->runtime.sbuffer; - int totpoints = gpd->runtime.sbuffer_size; + int totpoints = gpd->runtime.sbuffer_used; if (totpoints < 3) { return NULL; } diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index 181d2efbabb..9b755217946 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -1493,7 +1493,7 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, /* Check if may need to draw the active stroke cache, only if this layer is the active layer * that is being edited. (Stroke buffer is currently stored in gp-data) */ - if (gpd->runtime.sbuffer_size > 0) { + if (gpd->runtime.sbuffer_used > 0) { if ((gpd->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) { /* It should also be noted that sbuffer contains temporary point types * i.e. tGPspoints NOT bGPDspoints @@ -1506,7 +1506,7 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, stl->storage->alignment_mode = (gp_style) ? gp_style->alignment_mode : GP_STYLE_FOLLOW_PATH; /* if only one point, don't need to draw buffer because the user has no time to see it */ - if (gpd->runtime.sbuffer_size > 1) { + if (gpd->runtime.sbuffer_used > 1) { if ((gp_style) && (gp_style->mode == GP_STYLE_MODE_LINE)) { stl->g_data->shgrps_drawing_stroke = gpencil_shgroup_stroke_create( vedata, @@ -1562,7 +1562,7 @@ void gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, DRW_shgroup_call( stl->g_data->shgrps_drawing_stroke, stl->g_data->batch_buffer_stroke, NULL); - if ((gpd->runtime.sbuffer_size >= 3) && + if ((gpd->runtime.sbuffer_used >= 3) && (gpd->runtime.sfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) && ((gpd->runtime.sbuffer_sflag & GP_STROKE_NOFILL) == 0) && ((brush->gpencil_settings->flag & GP_BRUSH_DISSABLE_LASSO) == 0) && diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 408c9759682..5f6f5650ca7 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -435,7 +435,7 @@ void GPENCIL_cache_init(void *vedata) /* need the original to avoid cow overhead while drawing */ bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&obact_gpd->id); if (((gpd_orig->runtime.sbuffer_sflag & GP_STROKE_ERASER) == 0) && - (gpd_orig->runtime.sbuffer_size > 0) && + (gpd_orig->runtime.sbuffer_used > 0) && ((gpd_orig->flag & GP_DATA_STROKE_POLYGON) == 0) && !DRW_state_is_depth() && (stl->storage->background_ready == true)) { stl->g_data->session_flag |= GP_DRW_PAINT_PAINTING; diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c index 379b4e77514..327765c07b2 100644 --- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c +++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c @@ -463,12 +463,11 @@ static void gpencil_fx_shadow(ShaderFxData *fx, DRW_shgroup_uniform_vec3(fx_shgrp, "loc", fxd->runtime.loc, 1); } - const int nowave = -1; if (fxd->flag & FX_SHADOW_USE_WAVE) { DRW_shgroup_uniform_int(fx_shgrp, "orientation", &fxd->orientation, 1); } else { - DRW_shgroup_uniform_int(fx_shgrp, "orientation", &nowave, 1); + DRW_shgroup_uniform_int_copy(fx_shgrp, "orientation", -1); } DRW_shgroup_uniform_float(fx_shgrp, "amplitude", &fxd->amplitude, 1); DRW_shgroup_uniform_float(fx_shgrp, "period", &fxd->period, 1); diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl index b226d4f93bc..01d4fe40195 100644 --- a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl @@ -42,7 +42,11 @@ void main() vec2 tc = uv - center; float dist = length(tc); - float pxradius = (ProjectionMatrix[3][3] == 0.0) ? (radius / (loc.z * defaultpixsize)) : + float locpixsize = abs((loc.z * defaultpixsize)); + if (locpixsize == 0) { + locpixsize = 1; + } + float pxradius = (ProjectionMatrix[3][3] == 0.0) ? (radius / locpixsize) : (radius / defaultpixsize); pxradius = max(pxradius, 1); diff --git a/source/blender/draw/engines/select/select_draw_utils.c b/source/blender/draw/engines/select/select_draw_utils.c new file mode 100644 index 00000000000..08c6c2ac865 --- /dev/null +++ b/source/blender/draw/engines/select/select_draw_utils.c @@ -0,0 +1,215 @@ +/* + * 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 2019, Blender Foundation. + */ + +/** \file + * \ingroup draw_engine + * + * Engine for drawing a selection map where the pixels indicate the selection indices. + */ + +#include "BKE_editmesh.h" + +#include "DNA_mesh_types.h" +#include "DNA_scene_types.h" + +#include "ED_view3d.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "draw_cache_impl.h" + +#include "select_private.h" + +/* -------------------------------------------------------------------- */ +/** \name Draw Utilities + * \{ */ + +static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, char dt) +{ + if (select_mode & SCE_SELECT_FACE) { + if ((dt < OB_SOLID) || XRAY_FLAG_ENABLED(v3d)) { + return true; + } + if (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) { + return true; + } + if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) { + /* Since we can't deduce face selection when edges aren't visible - show dots. */ + return true; + } + } + return false; +} + +static void draw_select_id_edit_mesh(SELECTID_StorageList *stl, + Object *ob, + short select_mode, + bool draw_facedot, + uint initial_offset, + uint *r_vert_offset, + uint *r_edge_offset, + uint *r_face_offset) +{ + Mesh *me = ob->data; + BMEditMesh *em = me->edit_mesh; + + BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); + + struct GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me); + DRWShadingGroup *face_shgrp; + if (select_mode & SCE_SELECT_FACE) { + face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_flat); + DRW_shgroup_uniform_int_copy(face_shgrp, "offset", *(int *)&initial_offset); + + if (draw_facedot) { + struct GPUBatch *geom_facedots = DRW_mesh_batch_cache_get_facedots_with_select_id(me); + DRW_shgroup_call(face_shgrp, geom_facedots, ob); + } + *r_face_offset = initial_offset + em->bm->totface; + } + else { + face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_unif); + DRW_shgroup_uniform_int_copy(face_shgrp, "id", 0); + + *r_face_offset = initial_offset; + } + DRW_shgroup_call(face_shgrp, geom_faces, ob); + + /* Unlike faces, only draw edges if edge select mode. */ + if (select_mode & SCE_SELECT_EDGE) { + struct GPUBatch *geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me); + DRWShadingGroup *edge_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_edge); + DRW_shgroup_uniform_int_copy(edge_shgrp, "offset", *(int *)r_face_offset); + DRW_shgroup_call(edge_shgrp, geom_edges, ob); + *r_edge_offset = *r_face_offset + em->bm->totedge; + } + else { + /* Note that `r_vert_offset` is calculated from `r_edge_offset`. + * Otherwise the first vertex is never selected, see: T53512. */ + *r_edge_offset = *r_face_offset; + } + + /* Unlike faces, only verts if vert select mode. */ + if (select_mode & SCE_SELECT_VERTEX) { + struct GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me); + DRWShadingGroup *vert_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_vert); + DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", *(int *)r_edge_offset); + DRW_shgroup_call(vert_shgrp, geom_verts, ob); + *r_vert_offset = *r_edge_offset + em->bm->totvert; + } + else { + *r_vert_offset = *r_edge_offset; + } +} + +static void draw_select_id_mesh(SELECTID_StorageList *stl, + Object *ob, + short select_mode, + uint initial_offset, + uint *r_vert_offset, + uint *r_edge_offset, + uint *r_face_offset) +{ + Mesh *me = ob->data; + + struct GPUBatch *geom_faces = DRW_mesh_batch_cache_get_triangles_with_select_id(me); + DRWShadingGroup *face_shgrp; + if (select_mode & SCE_SELECT_FACE) { + face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_flat); + DRW_shgroup_uniform_int_copy(face_shgrp, "offset", *(int *)&initial_offset); + *r_face_offset = initial_offset + me->totpoly; + } + else { + /* Only draw faces to mask out verts, we don't want their selection ID's. */ + face_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_face_unif); + DRW_shgroup_uniform_int_copy(face_shgrp, "id", 0); + *r_face_offset = initial_offset; + } + DRW_shgroup_call(face_shgrp, geom_faces, ob); + + if (select_mode & SCE_SELECT_EDGE) { + struct GPUBatch *geom_edges = DRW_mesh_batch_cache_get_edges_with_select_id(me); + DRWShadingGroup *edge_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_edge); + DRW_shgroup_uniform_int_copy(edge_shgrp, "offset", *(int *)r_face_offset); + DRW_shgroup_call(edge_shgrp, geom_edges, ob); + *r_edge_offset = *r_face_offset + me->totedge; + } + else { + *r_edge_offset = *r_face_offset; + } + + if (select_mode & SCE_SELECT_VERTEX) { + struct GPUBatch *geom_verts = DRW_mesh_batch_cache_get_verts_with_select_id(me); + DRWShadingGroup *vert_shgrp = DRW_shgroup_create_sub(stl->g_data->shgrp_vert); + DRW_shgroup_uniform_int_copy(vert_shgrp, "offset", 1); + DRW_shgroup_call(vert_shgrp, geom_verts, ob); + *r_vert_offset = *r_edge_offset + me->totvert; + } +} + +void select_id_draw_object(void *vedata, + View3D *v3d, + Object *ob, + short select_mode, + uint initial_offset, + uint *r_vert_offset, + uint *r_edge_offset, + uint *r_face_offset) +{ + SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl; + + BLI_assert(initial_offset > 0); + + switch (ob->type) { + case OB_MESH: + if (ob->mode & OB_MODE_EDIT) { + bool draw_facedot = check_ob_drawface_dot(select_mode, v3d, ob->dt); + draw_select_id_edit_mesh(stl, + ob, + select_mode, + draw_facedot, + initial_offset, + r_vert_offset, + r_edge_offset, + r_face_offset); + } + else { + if (ob->mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_TEXTURE_PAINT)) { + Mesh *me_orig = DEG_get_original_object(ob)->data; + select_mode = 0; + if (me_orig->editflag & ME_EDIT_PAINT_FACE_SEL) { + select_mode = SCE_SELECT_FACE; + } + if (me_orig->editflag & ME_EDIT_PAINT_VERT_SEL) { + select_mode |= SCE_SELECT_VERTEX; + } + } + draw_select_id_mesh( + stl, ob, select_mode, initial_offset, r_vert_offset, r_edge_offset, r_face_offset); + } + break; + case OB_CURVE: + case OB_SURF: + break; + } +} + +/** \} */ + +#undef SELECT_ENGINE diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c new file mode 100644 index 00000000000..68b4a8084f0 --- /dev/null +++ b/source/blender/draw/engines/select/select_engine.c @@ -0,0 +1,435 @@ +/* + * 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 2019, Blender Foundation. + */ + +/** \file + * \ingroup draw_engine + * + * Engine for drawing a selection map where the pixels indicate the selection indices. + */ + +#include "BLI_rect.h" + +#include "DNA_screen_types.h" + +#include "GPU_shader.h" +#include "GPU_select.h" + +#include "UI_resources.h" + +#include "DRW_engine.h" + +#include "select_private.h" +#include "select_engine.h" + +#define SELECT_ENGINE "SELECT_ENGINE" + +/* *********** STATIC *********** */ + +static struct { + SELECTID_Shaders sh_data[GPU_SHADER_CFG_LEN]; + + struct GPUFrameBuffer *framebuffer_select_id; + struct GPUTexture *texture_u32; + + struct { + struct BaseOffset *base_array_index_offsets; + uint bases_len; + uint last_base_drawn; + /** Total number of items `base_array_index_offsets[bases_len - 1].vert`. */ + uint last_index_drawn; + + short select_mode; + } context; +} e_data = {{{NULL}}}; /* Engine data */ + +/* Shaders */ +extern char datatoc_common_view_lib_glsl[]; +extern char datatoc_selection_id_3D_vert_glsl[]; +extern char datatoc_selection_id_frag_glsl[]; + +/* -------------------------------------------------------------------- */ +/** \name Selection Utilities + * \{ */ + +static void draw_select_framebuffer_select_id_setup(void) +{ + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + int size[2]; + size[0] = GPU_texture_width(dtxl->depth); + size[1] = GPU_texture_height(dtxl->depth); + + if (e_data.framebuffer_select_id == NULL) { + e_data.framebuffer_select_id = GPU_framebuffer_create(); + } + + if ((e_data.texture_u32 != NULL) && ((GPU_texture_width(e_data.texture_u32) != size[0]) || + (GPU_texture_height(e_data.texture_u32) != size[1]))) { + + GPU_texture_free(e_data.texture_u32); + e_data.texture_u32 = NULL; + } + + /* Make sure the depth texture is attached. + * It may disappear when loading another Blender session. */ + GPU_framebuffer_texture_attach(e_data.framebuffer_select_id, dtxl->depth, 0, 0); + + if (e_data.texture_u32 == NULL) { + e_data.texture_u32 = GPU_texture_create_2d(size[0], size[1], GPU_R32UI, NULL, NULL); + GPU_framebuffer_texture_attach(e_data.framebuffer_select_id, e_data.texture_u32, 0, 0); + GPU_framebuffer_check_valid(e_data.framebuffer_select_id, NULL); + } +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Engine Functions + * \{ */ + +static void select_engine_init(void *vedata) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + eGPUShaderConfig sh_cfg = draw_ctx->sh_cfg; + + SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl; + SELECTID_Shaders *sh_data = &e_data.sh_data[sh_cfg]; + + /* Prepass */ + if (!sh_data->select_id_flat) { + const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg]; + sh_data->select_id_flat = GPU_shader_create_from_arrays({ + .vert = (const char *[]){sh_cfg_data->lib, + datatoc_common_view_lib_glsl, + datatoc_selection_id_3D_vert_glsl, + NULL}, + .frag = (const char *[]){datatoc_selection_id_frag_glsl, NULL}, + .defs = (const char *[]){sh_cfg_data->def, NULL}, + }); + } + if (!sh_data->select_id_uniform) { + const GPUShaderConfigData *sh_cfg_data = &GPU_shader_cfg_data[sh_cfg]; + sh_data->select_id_uniform = GPU_shader_create_from_arrays({ + .vert = (const char *[]){sh_cfg_data->lib, + datatoc_common_view_lib_glsl, + datatoc_selection_id_3D_vert_glsl, + NULL}, + .frag = (const char *[]){datatoc_selection_id_frag_glsl, NULL}, + .defs = (const char *[]){sh_cfg_data->def, "#define UNIFORM_ID\n", NULL}, + }); + } + + if (!stl->g_data) { + /* Alloc transient pointers */ + stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); + } + + { + /* Create view with depth offset */ + stl->g_data->view_faces = (DRWView *)DRW_view_default_get(); + stl->g_data->view_edges = DRW_view_create_with_zoffset(draw_ctx->rv3d, 1.0f); + stl->g_data->view_verts = DRW_view_create_with_zoffset(draw_ctx->rv3d, 1.1f); + } +} + +static void select_cache_init(void *vedata) +{ + SELECTID_PassList *psl = ((SELECTID_Data *)vedata)->psl; + SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl; + + const DRWContextState *draw_ctx = DRW_context_state_get(); + SELECTID_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; + { + psl->select_id_face_pass = DRW_pass_create("Face Pass", DRW_STATE_DEFAULT); + stl->g_data->shgrp_face_unif = DRW_shgroup_create(sh_data->select_id_uniform, + psl->select_id_face_pass); + + stl->g_data->shgrp_face_flat = DRW_shgroup_create(sh_data->select_id_flat, + psl->select_id_face_pass); + + psl->select_id_edge_pass = DRW_pass_create( + "Edge Pass", DRW_STATE_DEFAULT | DRW_STATE_FIRST_VERTEX_CONVENTION); + + stl->g_data->shgrp_edge = DRW_shgroup_create(sh_data->select_id_flat, + psl->select_id_edge_pass); + + psl->select_id_vert_pass = DRW_pass_create("Vert Pass", DRW_STATE_DEFAULT); + stl->g_data->shgrp_vert = DRW_shgroup_create(sh_data->select_id_flat, + psl->select_id_vert_pass); + + DRW_shgroup_uniform_float_copy(stl->g_data->shgrp_vert, "sizeVertex", G_draw.block.sizeVertex); + + if (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) { + DRW_shgroup_state_enable(stl->g_data->shgrp_face_unif, DRW_STATE_CLIP_PLANES); + DRW_shgroup_state_enable(stl->g_data->shgrp_face_flat, DRW_STATE_CLIP_PLANES); + DRW_shgroup_state_enable(stl->g_data->shgrp_edge, DRW_STATE_CLIP_PLANES); + DRW_shgroup_state_enable(stl->g_data->shgrp_vert, DRW_STATE_CLIP_PLANES); + } + } + + e_data.context.last_base_drawn = 0; + e_data.context.last_index_drawn = 1; +} + +static void select_cache_populate(void *vedata, Object *ob) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + short select_mode = e_data.context.select_mode; + + if (select_mode == -1) { + ToolSettings *ts = draw_ctx->scene->toolsettings; + select_mode = ts->selectmode; + } + + struct BaseOffset *base_ofs = + &e_data.context.base_array_index_offsets[e_data.context.last_base_drawn++]; + + uint offset = e_data.context.last_index_drawn; + + select_id_draw_object(vedata, + draw_ctx->v3d, + ob, + select_mode, + offset, + &base_ofs->vert, + &base_ofs->edge, + &base_ofs->face); + + base_ofs->offset = offset; + e_data.context.last_index_drawn = base_ofs->vert; +} + +static void select_draw_scene(void *vedata) +{ + SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl; + SELECTID_PassList *psl = ((SELECTID_Data *)vedata)->psl; + + /* Setup framebuffer */ + draw_select_framebuffer_select_id_setup(); + GPU_framebuffer_bind(e_data.framebuffer_select_id); + + /* dithering and AA break color coding, so disable */ + glDisable(GL_DITHER); + + GPU_framebuffer_clear_color_depth(e_data.framebuffer_select_id, (const float[4]){0.0f}, 1.0f); + + DRW_view_set_active(stl->g_data->view_faces); + DRW_draw_pass(psl->select_id_face_pass); + + DRW_view_set_active(stl->g_data->view_edges); + DRW_draw_pass(psl->select_id_edge_pass); + + DRW_view_set_active(stl->g_data->view_verts); + DRW_draw_pass(psl->select_id_vert_pass); +} + +static void select_engine_free(void) +{ + for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) { + SELECTID_Shaders *sh_data = &e_data.sh_data[sh_data_index]; + DRW_SHADER_FREE_SAFE(sh_data->select_id_flat); + DRW_SHADER_FREE_SAFE(sh_data->select_id_uniform); + } + + DRW_TEXTURE_FREE_SAFE(e_data.texture_u32); + GPU_FRAMEBUFFER_FREE_SAFE(e_data.framebuffer_select_id); + MEM_SAFE_FREE(e_data.context.base_array_index_offsets); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Exposed `DRW_engine.h` functions + * \{ */ + +bool DRW_select_elem_get(const uint sel_id, uint *r_elem, uint *r_base_index, char *r_elem_type) +{ + char elem_type = 0; + uint elem_id; + uint base_index = 0; + + for (; base_index < e_data.context.bases_len; base_index++) { + struct BaseOffset *base_ofs = &e_data.context.base_array_index_offsets[base_index]; + + if (base_ofs->face > sel_id) { + elem_id = sel_id - base_ofs->face_start; + elem_type = SCE_SELECT_FACE; + break; + } + if (base_ofs->edge > sel_id) { + elem_id = sel_id - base_ofs->edge_start; + elem_type = SCE_SELECT_EDGE; + break; + } + if (base_ofs->vert > sel_id) { + elem_id = sel_id - base_ofs->vert_start; + elem_type = SCE_SELECT_VERTEX; + break; + } + } + + if (base_index == e_data.context.bases_len) { + return false; + } + + *r_elem = elem_id; + + if (r_base_index) { + *r_base_index = base_index; + } + + if (r_elem_type) { + *r_elem_type = elem_type; + } + + return true; +} + +uint DRW_select_context_offset_for_object_elem(const uint base_index, char elem_type) +{ + struct BaseOffset *base_ofs = &e_data.context.base_array_index_offsets[base_index]; + + if (elem_type == SCE_SELECT_VERTEX) { + return base_ofs->vert_start - 1; + } + if (elem_type == SCE_SELECT_EDGE) { + return base_ofs->edge_start - 1; + } + if (elem_type == SCE_SELECT_FACE) { + return base_ofs->face_start - 1; + } + BLI_assert(0); + return 0; +} + +uint DRW_select_context_elem_len(void) +{ + return e_data.context.last_index_drawn; +} + +/* Read a block of pixels from the select frame buffer. */ +void DRW_framebuffer_select_id_read(const rcti *rect, uint *r_buf) +{ + /* clamp rect by texture */ + rcti r = { + .xmin = 0, + .xmax = GPU_texture_width(e_data.texture_u32), + .ymin = 0, + .ymax = GPU_texture_height(e_data.texture_u32), + }; + + rcti rect_clamp = *rect; + if (BLI_rcti_isect(&r, &rect_clamp, &rect_clamp)) { + DRW_opengl_context_enable(); + GPU_framebuffer_bind(e_data.framebuffer_select_id); + glReadBuffer(GL_COLOR_ATTACHMENT0); + glReadPixels(rect_clamp.xmin, + rect_clamp.ymin, + BLI_rcti_size_x(&rect_clamp), + BLI_rcti_size_y(&rect_clamp), + GL_RED_INTEGER, + GL_UNSIGNED_INT, + r_buf); + + GPU_framebuffer_restore(); + DRW_opengl_context_disable(); + + if (!BLI_rcti_compare(rect, &rect_clamp)) { + GPU_select_buffer_stride_realign(rect, &rect_clamp, r_buf); + } + } + else { + size_t buf_size = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect) * sizeof(*r_buf); + + memset(r_buf, 0, buf_size); + } +} + +void DRW_select_context_create(Base **UNUSED(bases), const uint bases_len, short select_mode) +{ + e_data.context.select_mode = select_mode; + e_data.context.bases_len = bases_len; + + MEM_SAFE_FREE(e_data.context.base_array_index_offsets); + e_data.context.base_array_index_offsets = MEM_mallocN( + sizeof(*e_data.context.base_array_index_offsets) * bases_len, __func__); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Legacy + * \{ */ + +void DRW_draw_select_id_object(Depsgraph *depsgraph, + ViewLayer *view_layer, + ARegion *ar, + View3D *v3d, + Object *ob, + short select_mode) +{ + Base *base = BKE_view_layer_base_find(view_layer, ob); + DRW_draw_select_id(depsgraph, ar, v3d, &base, 1, select_mode); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Engine Type + * \{ */ + +static const DrawEngineDataSize select_data_size = DRW_VIEWPORT_DATA_SIZE(SELECTID_Data); + +DrawEngineType draw_engine_select_type = { + NULL, + NULL, + N_("Select ID"), + &select_data_size, + &select_engine_init, + &select_engine_free, + &select_cache_init, + &select_cache_populate, + NULL, + NULL, + &select_draw_scene, + NULL, + NULL, + NULL, +}; + +/* Note: currently unused, we may want to register so we can see this when debugging the view. */ + +RenderEngineType DRW_engine_viewport_select_type = { + NULL, + NULL, + SELECT_ENGINE, + N_("Select ID"), + RE_INTERNAL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &draw_engine_select_type, + {NULL, NULL, NULL}, +}; + +/** \} */ + +#undef SELECT_ENGINE diff --git a/source/blender/draw/engines/select/select_engine.h b/source/blender/draw/engines/select/select_engine.h new file mode 100644 index 00000000000..5b900ccaf27 --- /dev/null +++ b/source/blender/draw/engines/select/select_engine.h @@ -0,0 +1,29 @@ +/* + * 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 2019, Blender Foundation. + */ + +/** \file + * \ingroup draw_engine + */ + +#ifndef __SELECT_ENGINE_H__ +#define __SELECT_ENGINE_H__ + +extern DrawEngineType draw_engine_select_type; +extern RenderEngineType DRW_engine_viewport_select_type; + +#endif /* __SELECT_ID_ENGINE_H__ */ diff --git a/source/blender/draw/engines/select/select_private.h b/source/blender/draw/engines/select/select_private.h new file mode 100644 index 00000000000..9b0addb0fb8 --- /dev/null +++ b/source/blender/draw/engines/select/select_private.h @@ -0,0 +1,91 @@ +/* + * 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 2019, Blender Foundation. + */ + +/** \file + * \ingroup draw_engine + */ + +#ifndef __SELECT_PRIVATE_H__ +#define __SELECT_PRIVATE_H__ + +#include "DRW_render.h" + +/* GPUViewport.storage + * Is freed everytime the viewport engine changes */ +typedef struct SELECTID_StorageList { + struct SELECTID_PrivateData *g_data; +} SELECTID_StorageList; + +typedef struct SELECTID_PassList { + struct DRWPass *select_id_face_pass; + struct DRWPass *select_id_edge_pass; + struct DRWPass *select_id_vert_pass; +} SELECTID_PassList; + +typedef struct SELECTID_Data { + void *engine_type; + DRWViewportEmptyList *fbl; + DRWViewportEmptyList *txl; + SELECTID_PassList *psl; + SELECTID_StorageList *stl; +} SELECTID_Data; + +typedef struct SELECTID_Shaders { + /* Depth Pre Pass */ + struct GPUShader *select_id_flat; + struct GPUShader *select_id_uniform; +} SELECTID_Shaders; + +typedef struct SELECTID_PrivateData { + DRWShadingGroup *shgrp_face_unif; + DRWShadingGroup *shgrp_face_flat; + DRWShadingGroup *shgrp_edge; + DRWShadingGroup *shgrp_vert; + + DRWView *view_faces; + DRWView *view_edges; + DRWView *view_verts; +} SELECTID_PrivateData; /* Transient data */ + +struct BaseOffset { + /* For convenience only. */ + union { + uint offset; + uint face_start; + }; + union { + uint face; + uint edge_start; + }; + union { + uint edge; + uint vert_start; + }; + uint vert; +}; + +void select_id_draw_object(void *vedata, + View3D *v3d, + Object *ob, + short select_mode, + uint initial_offset, + uint *r_vert_offset, + uint *r_edge_offset, + uint *r_face_offset); + +#endif /* __SELECT_PRIVATE_H__ */ diff --git a/source/blender/draw/engines/select/shaders/selection_id_3D_vert.glsl b/source/blender/draw/engines/select/shaders/selection_id_3D_vert.glsl new file mode 100644 index 00000000000..9b0107cffdb --- /dev/null +++ b/source/blender/draw/engines/select/shaders/selection_id_3D_vert.glsl @@ -0,0 +1,26 @@ + +uniform float sizeVertex; + +in vec3 pos; + +#ifndef UNIFORM_ID +uniform int offset; +in uint color; + +flat out uint id; +#endif + +void main() +{ +#ifndef UNIFORM_ID + id = floatBitsToUint(intBitsToFloat(offset)) + color; +#endif + + vec3 world_pos = point_object_to_world(pos); + gl_Position = point_world_to_ndc(world_pos); + gl_PointSize = sizeVertex; + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance(world_pos); +#endif +} diff --git a/source/blender/draw/engines/select/shaders/selection_id_frag.glsl b/source/blender/draw/engines/select/shaders/selection_id_frag.glsl new file mode 100644 index 00000000000..ea86ddc7301 --- /dev/null +++ b/source/blender/draw/engines/select/shaders/selection_id_frag.glsl @@ -0,0 +1,14 @@ + +#ifdef UNIFORM_ID +uniform int id; +# define id floatBitsToUint(intBitsToFloat(id)) +#else +flat in uint id; +#endif + +out uint fragColor; + +void main() +{ + fragColor = id; +} diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl index 8d66cd7b26c..a0e04f252e2 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_frag.glsl @@ -46,7 +46,7 @@ vec3 get_view_space_from_depth(in vec2 uvcoords, in float depth) } } -/* forward declartion */ +/* forward declaration */ void ssao_factors(in float depth, in vec3 normal, in vec3 position, diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl index 1af786b648c..376b19cdd1b 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl @@ -58,7 +58,7 @@ void ssao_factors(in float depth, /* Handle Background case */ bool is_background = (depth_new == 1.0); - /* This trick provide good edge effect even if no neighboor is found. */ + /* This trick provide good edge effect even if no neighbor is found. */ vec3 pos_new = get_view_space_from_depth(uvcoords, (is_background) ? depth : depth_new); if (is_background) { diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c index 575da1f9683..1beb02ea3a0 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.c +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -161,7 +161,7 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, sds->slice_axis - 1; float dim[3]; BKE_object_dimensions_get(ob, dim); - /* 0.05f to acheive somewhat the same opacity as the full view. */ + /* 0.05f to achieve somewhat the same opacity as the full view. */ float step_length = max_ff(1e-16f, dim[axis] * 0.05f); grp = DRW_shgroup_create(sh, vedata->psl->volume_pass); |