diff options
Diffstat (limited to 'source/blender/draw/modes')
18 files changed, 412 insertions, 73 deletions
diff --git a/source/blender/draw/modes/draw_mode_engines.h b/source/blender/draw/modes/draw_mode_engines.h index f88d49dfa96..8e8ddfef5a4 100644 --- a/source/blender/draw/modes/draw_mode_engines.h +++ b/source/blender/draw/modes/draw_mode_engines.h @@ -42,5 +42,6 @@ extern DrawEngineType draw_engine_particle_type; extern DrawEngineType draw_engine_pose_type; extern DrawEngineType draw_engine_sculpt_type; extern DrawEngineType draw_engine_overlay_type; +extern DrawEngineType draw_engine_gpencil_type; #endif /* __DRAW_MODE_ENGINES_H__ */ diff --git a/source/blender/draw/modes/edit_armature_mode.c b/source/blender/draw/modes/edit_armature_mode.c index 285e703afbf..1e8293b5dbb 100644 --- a/source/blender/draw/modes/edit_armature_mode.c +++ b/source/blender/draw/modes/edit_armature_mode.c @@ -60,7 +60,7 @@ typedef struct EDIT_ARMATURE_Data { /* *********** STATIC *********** */ typedef struct EDIT_ARMATURE_PrivateData { - char pad; /* UNUSED */ + bool transparent_bones; } EDIT_ARMATURE_PrivateData; /* Transient data */ /* *********** FUNCTIONS *********** */ @@ -69,15 +69,18 @@ static void EDIT_ARMATURE_cache_init(void *vedata) { EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl; EDIT_ARMATURE_StorageList *stl = ((EDIT_ARMATURE_Data *)vedata)->stl; + const DRWContextState *draw_ctx = DRW_context_state_get(); if (!stl->g_data) { /* Alloc transient pointers */ - stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); + stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__); } + stl->g_data->transparent_bones = (draw_ctx->v3d->overlay.arm_flag & V3D_OVERLAY_ARM_TRANSP_BONES) != 0; { /* Solid bones */ - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK; + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK; + state |= (stl->g_data->transparent_bones) ? DRW_STATE_BLEND : DRW_STATE_WRITE_DEPTH; psl->bone_solid = DRW_pass_create("Bone Solid Pass", state); } @@ -116,10 +119,12 @@ static void EDIT_ARMATURE_cache_init(void *vedata) static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob) { bArmature *arm = ob->data; - EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl; if (ob->type == OB_ARMATURE) { if (arm->edbo) { + EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl; + EDIT_ARMATURE_StorageList *stl = ((EDIT_ARMATURE_Data *)vedata)->stl; + DRWArmaturePasses passes = { .bone_solid = psl->bone_solid, .bone_outline = psl->bone_outline, @@ -128,7 +133,7 @@ static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob) .bone_axes = psl->bone_axes, .relationship_lines = psl->relationship, }; - DRW_shgroup_armature_edit(ob, passes); + DRW_shgroup_armature_edit(ob, passes, stl->g_data->transparent_bones); } } } @@ -136,22 +141,20 @@ static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob) static void EDIT_ARMATURE_draw_scene(void *vedata) { EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl; + EDIT_ARMATURE_StorageList *stl = ((EDIT_ARMATURE_Data *)vedata)->stl; DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const bool transparent_bones = (draw_ctx->v3d->overlay.arm_flag & V3D_OVERLAY_ARM_TRANSP_BONES) != 0; DRW_draw_pass(psl->bone_envelope); - if (transparent_bones) { - DRW_pass_state_add(psl->bone_solid, DRW_STATE_BLEND); - DRW_pass_state_remove(psl->bone_solid, DRW_STATE_WRITE_DEPTH); + if (stl->g_data->transparent_bones) { + /* For performance reason, avoid blending on MS target. */ DRW_draw_pass(psl->bone_solid); } MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl) - if (!transparent_bones) { + if (!stl->g_data->transparent_bones) { DRW_draw_pass(psl->bone_solid); } diff --git a/source/blender/draw/modes/edit_curve_mode.c b/source/blender/draw/modes/edit_curve_mode.c index 50ce29b7b1a..c8b8f678ca6 100644 --- a/source/blender/draw/modes/edit_curve_mode.c +++ b/source/blender/draw/modes/edit_curve_mode.c @@ -244,7 +244,7 @@ static void EDIT_CURVE_cache_populate(void *vedata, Object *ob) { Curve *cu = ob->data; /* Get geometry cache */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; geom = DRW_cache_curve_edge_wire_get(ob); DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat); diff --git a/source/blender/draw/modes/edit_lattice_mode.c b/source/blender/draw/modes/edit_lattice_mode.c index 870dd14d677..ca7903c555b 100644 --- a/source/blender/draw/modes/edit_lattice_mode.c +++ b/source/blender/draw/modes/edit_lattice_mode.c @@ -196,7 +196,7 @@ static void EDIT_LATTICE_cache_populate(void *vedata, Object *ob) if (ob->type == OB_LATTICE) { if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) { /* Get geometry cache */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; geom = DRW_cache_lattice_wire_get(ob, true); DRW_shgroup_call_add(stl->g_data->wire_shgrp, geom, ob->obmat); diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c index 1e05b154974..67a424b8081 100644 --- a/source/blender/draw/modes/edit_mesh_mode.c +++ b/source/blender/draw/modes/edit_mesh_mode.c @@ -365,7 +365,7 @@ static void EDIT_MESH_cache_init(void *vedata) const bool xray_enabled = ((draw_ctx->v3d->shading.flag & V3D_SHADING_XRAY) != 0) && - (draw_ctx->v3d->drawtype < OB_MATERIAL); + (draw_ctx->v3d->shading.type < OB_MATERIAL); stl->g_data->do_zbufclip = ((v3d->flag & V3D_ZBUF_SELECT) == 0) || xray_enabled; { @@ -432,7 +432,7 @@ static void EDIT_MESH_cache_init(void *vedata) DRW_shgroup_uniform_block(stl->g_data->facefill_occluded_shgrp, "globalsBlock", globals_ubo); /* we need a full screen pass to combine the result */ - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); psl->mix_occlude = DRW_pass_create( "Mix Occluded Wires", @@ -450,7 +450,7 @@ static void edit_mesh_add_ob_to_pass( Scene *scene, Object *ob, DRWShadingGroup *face_shgrp, DRWShadingGroup *ledges_shgrp, DRWShadingGroup *lverts_shgrp, DRWShadingGroup *facedot_shgrp, DRWShadingGroup *facefill_shgrp) { - struct Gwn_Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter; + struct GPUBatch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts, *geo_ovl_fcenter; ToolSettings *tsettings = scene->toolsettings; DRW_cache_mesh_wire_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts); @@ -477,7 +477,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) const DRWContextState *draw_ctx = DRW_context_state_get(); View3D *v3d = draw_ctx->v3d; Scene *scene = draw_ctx->scene; - struct Gwn_Batch *geom; + struct GPUBatch *geom; if (ob->type == OB_MESH) { if ((ob == draw_ctx->object_edit) || BKE_object_is_in_editmode(ob)) { @@ -512,7 +512,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) } if (vnormals_do || lnormals_do) { - struct Gwn_Batch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts; + struct GPUBatch *geo_ovl_tris, *geo_ovl_ledges, *geo_ovl_lverts; DRW_cache_mesh_normals_overlay_get(ob, &geo_ovl_tris, &geo_ovl_ledges, &geo_ovl_lverts); if (vnormals_do) { diff --git a/source/blender/draw/modes/edit_surface_mode.c b/source/blender/draw/modes/edit_surface_mode.c index 7074ba3d024..3c5d0dbf5a1 100644 --- a/source/blender/draw/modes/edit_surface_mode.c +++ b/source/blender/draw/modes/edit_surface_mode.c @@ -180,7 +180,7 @@ static void EDIT_SURFACE_cache_populate(void *vedata, Object *ob) if (ob->type == OB_MESH) { /* Get geometry cache */ - struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_surface_get(ob); /* Add geom to a shading group */ DRW_shgroup_call_add(stl->g_data->group, geom, ob->obmat); diff --git a/source/blender/draw/modes/edit_text_mode.c b/source/blender/draw/modes/edit_text_mode.c index 5750dc8a0b9..f21715ef399 100644 --- a/source/blender/draw/modes/edit_text_mode.c +++ b/source/blender/draw/modes/edit_text_mode.c @@ -197,7 +197,7 @@ static void EDIT_TEXT_cache_populate(void *vedata, Object *ob) if (ob == draw_ctx->object_edit) { const Curve *cu = ob->data; /* Get geometry cache */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; if (cu->flag & CU_FAST) { geom = DRW_cache_text_edge_wire_get(ob); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 834a90ba3cf..e0a78c48a4c 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -37,6 +37,7 @@ #include "DNA_lightprobe_types.h" #include "DNA_particle_types.h" #include "DNA_rigidbody_types.h" +#include "DNA_smoke_types.h" #include "DNA_view3d_types.h" #include "DNA_world_types.h" @@ -60,6 +61,7 @@ #include "GPU_shader.h" #include "GPU_texture.h" +#include "GPU_draw.h" #include "MEM_guardedalloc.h" @@ -144,6 +146,9 @@ typedef struct OBJECT_PrivateData { DRWShadingGroup *cube; DRWShadingGroup *circle; DRWShadingGroup *sphere; + DRWShadingGroup *cylinder; + DRWShadingGroup *capsule_cap; + DRWShadingGroup *capsule_body; DRWShadingGroup *cone; DRWShadingGroup *single_arrow; DRWShadingGroup *single_arrow_line; @@ -161,6 +166,9 @@ typedef struct OBJECT_PrivateData { DRWShadingGroup *field_tube_limit; DRWShadingGroup *field_cone_limit; + /* Grease Pencil */ + DRWShadingGroup *gpencil_axes; + /* Speaker */ DRWShadingGroup *speaker; @@ -254,9 +262,9 @@ typedef struct OBJECT_PrivateData { static struct { /* Instance Data format */ - struct Gwn_VertFormat *particle_format; - struct Gwn_VertFormat *empty_image_format; - struct Gwn_VertFormat *empty_image_wire_format; + struct GPUVertFormat *particle_format; + struct GPUVertFormat *empty_image_format; + struct GPUVertFormat *empty_image_wire_format; /* fullscreen shaders */ GPUShader *outline_prepass_sh; @@ -292,6 +300,8 @@ static struct { struct GPUTexture *outlines_id_tx; struct GPUTexture *outlines_color_tx; struct GPUTexture *outlines_blur_tx; + + ListBase smoke_domains; } e_data = {NULL}; /* Engine data */ @@ -848,7 +858,7 @@ static void DRW_shgroup_empty_image( {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}, }); - struct Gwn_Batch *geom = DRW_cache_image_plane_get(); + struct GPUBatch *geom = DRW_cache_image_plane_get(); DRWShadingGroup *grp = DRW_shgroup_instance_create( e_data.object_empty_image_sh, psl->non_meshes, geom, e_data.empty_image_format); DRW_shgroup_uniform_texture(grp, "image", tex); @@ -868,7 +878,7 @@ static void DRW_shgroup_empty_image( {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16} }); - struct Gwn_Batch *geom = DRW_cache_image_plane_wire_get(); + struct GPUBatch *geom = DRW_cache_image_plane_wire_get(); DRWShadingGroup *grp = DRW_shgroup_instance_create( e_data.object_empty_image_wire_sh, psl->non_meshes, geom, e_data.empty_image_wire_format); DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1); @@ -904,7 +914,7 @@ static void OBJECT_cache_init(void *vedata) OBJECT_PrivateData *g_data; const DRWContextState *draw_ctx = DRW_context_state_get(); const bool xray_enabled = ((draw_ctx->v3d->shading.flag & V3D_SHADING_XRAY) != 0) && - (draw_ctx->v3d->drawtype < OB_MATERIAL); + (draw_ctx->v3d->shading.type < OB_MATERIAL); /* TODO : use dpi setting for enabling the second pass */ const bool do_outline_expand = false; @@ -937,8 +947,8 @@ static void OBJECT_cache_init(void *vedata) { DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_POINT; DRWPass *pass = psl->lightprobes = DRW_pass_create("Object Probe Pass", state); - struct Gwn_Batch *sphere = DRW_cache_sphere_get(); - struct Gwn_Batch *quad = DRW_cache_quad_get(); + struct GPUBatch *sphere = DRW_cache_sphere_get(); + struct GPUBatch *quad = DRW_cache_quad_get(); /* Cubemap */ g_data->lightprobes_cube_select = shgroup_instance_outline(pass, sphere, &g_data->id_ofs_prb_select); @@ -957,7 +967,7 @@ static void OBJECT_cache_init(void *vedata) { DRWState state = DRW_STATE_WRITE_COLOR; - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); /* Don't occlude the "outline" detection pass if in xray mode (too much flickering). */ float alphaOcclu = (xray_enabled) ? 1.0f : 0.35f; /* Reminder : bool uniforms need to be 4 bytes. */ @@ -997,7 +1007,7 @@ static void OBJECT_cache_init(void *vedata) DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND; psl->outlines_resolve = DRW_pass_create("Outlines Resolve Pass", state); - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); GPUTexture **outline_tx = (do_outline_expand) ? &e_data.outlines_blur_tx : &e_data.outlines_color_tx; DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_resolve_aa_sh, psl->outlines_resolve); @@ -1011,7 +1021,7 @@ static void OBJECT_cache_init(void *vedata) DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND; psl->grid = DRW_pass_create("Infinite Grid Pass", state); - struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get(); + struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); static float mat[4][4]; unit_m4(mat); @@ -1072,7 +1082,7 @@ static void OBJECT_cache_init(void *vedata) { /* Non Meshes Pass (Camera, empties, lamps ...) */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | @@ -1084,7 +1094,7 @@ static void OBJECT_cache_init(void *vedata) geom = DRW_cache_plain_axes_get(); stl->g_data->plain_axes = shgroup_instance(psl->non_meshes, geom); - geom = DRW_cache_cube_get(); + geom = DRW_cache_empty_cube_get(); stl->g_data->cube = shgroup_instance(psl->non_meshes, geom); geom = DRW_cache_circle_get(); @@ -1093,6 +1103,15 @@ static void OBJECT_cache_init(void *vedata) geom = DRW_cache_empty_sphere_get(); stl->g_data->sphere = shgroup_instance(psl->non_meshes, geom); + geom = DRW_cache_empty_cylinder_get(); + stl->g_data->cylinder = shgroup_instance(psl->non_meshes, geom); + + geom = DRW_cache_empty_capsule_cap_get(); + stl->g_data->capsule_cap = shgroup_instance(psl->non_meshes, geom); + + geom = DRW_cache_empty_capsule_body_get(); + stl->g_data->capsule_body = shgroup_instance(psl->non_meshes, geom); + geom = DRW_cache_empty_cone_get(); stl->g_data->cone = shgroup_instance(psl->non_meshes, geom); @@ -1124,6 +1143,10 @@ static void OBJECT_cache_init(void *vedata) geom = DRW_cache_screenspace_circle_get(); stl->g_data->field_curve_sta = shgroup_instance_screen_aligned(psl->non_meshes, geom); + /* Grease Pencil */ + geom = DRW_cache_gpencil_axes_get(); + stl->g_data->gpencil_axes = shgroup_instance(psl->non_meshes, geom); + /* Speaker */ geom = DRW_cache_speaker_get(); stl->g_data->speaker = shgroup_instance(psl->non_meshes, geom); @@ -1162,7 +1185,7 @@ static void OBJECT_cache_init(void *vedata) stl->g_data->camera_mist_points = shgroup_distance_lines_instance(psl->non_meshes, geom); /* Texture Space */ - geom = DRW_cache_cube_get(); + geom = DRW_cache_empty_cube_get(); stl->g_data->texspace = shgroup_instance(psl->non_meshes, geom); } @@ -1209,7 +1232,7 @@ static void OBJECT_cache_init(void *vedata) /* TODO * for now we create multiple times the same VBO with only lamp center coordinates * but ideally we would only create it once */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; /* start with buflimit because we don't want stipples */ geom = DRW_cache_single_line_get(); @@ -1261,7 +1284,7 @@ static void OBJECT_cache_init(void *vedata) { /* -------- STIPPLES ------- */ - struct Gwn_Batch *geom; + struct GPUBatch *geom; /* Relationship Lines */ stl->g_data->relationship_lines = shgroup_dynlines_dashed_uniform_color(psl->non_meshes, ts.colorWire); @@ -1665,7 +1688,7 @@ static void DRW_shgroup_forcefield(OBJECT_StorageList *stl, Object *ob, ViewLaye } break; case PFIELD_GUIDE: - if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) { + if (cu && (cu->flag & CU_PATH) && ob->runtime.curve_cache->path && ob->runtime.curve_cache->path->data) { where_on_path(ob, 0.0f, pd->drawvec1, tmp, NULL, NULL, NULL); where_on_path(ob, 1.0f, pd->drawvec2, tmp, NULL, NULL, NULL); } @@ -1706,7 +1729,7 @@ static void DRW_shgroup_forcefield(OBJECT_StorageList *stl, Object *ob, ViewLaye DRW_shgroup_call_dynamic_add(stl->g_data->field_vortex, color, &pd->drawvec1, ob->obmat); break; case PFIELD_GUIDE: - if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) { + if (cu && (cu->flag & CU_PATH) && ob->runtime.curve_cache->path && ob->runtime.curve_cache->path->data) { DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_sta, color, &pd->f_strength, ob->obmat); DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_end, color, &pd->f_strength, ob->obmat); } @@ -1743,6 +1766,93 @@ static void DRW_shgroup_forcefield(OBJECT_StorageList *stl, Object *ob, ViewLaye } } +static void DRW_shgroup_volume_extra( + OBJECT_PassList *psl, OBJECT_StorageList *stl, + Object *ob, ViewLayer *view_layer, Scene *scene, ModifierData *md) +{ + SmokeModifierData *smd = (SmokeModifierData *)md; + SmokeDomainSettings *sds = smd->domain; + float *color; + float one = 1.0f; + + if (sds == NULL) { + return; + } + + DRW_object_wire_theme_get(ob, view_layer, &color); + + /* Small cube showing voxel size. */ + float voxel_cubemat[4][4] = {{0.0f}}; + voxel_cubemat[0][0] = 1.0f / (float)sds->res[0]; + voxel_cubemat[1][1] = 1.0f / (float)sds->res[1]; + voxel_cubemat[2][2] = 1.0f / (float)sds->res[2]; + voxel_cubemat[3][0] = voxel_cubemat[3][1] = voxel_cubemat[3][2] = -1.0f; + voxel_cubemat[3][3] = 1.0f; + translate_m4(voxel_cubemat, 1.0f, 1.0f, 1.0f); + mul_m4_m4m4(voxel_cubemat, ob->obmat, voxel_cubemat); + + DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &one, voxel_cubemat); + + /* Don't show smoke before simulation starts, this could be made an option in the future. */ + if (!sds->draw_velocity || !sds->fluid || CFRA < sds->point_cache[0]->startframe) { + return; + } + + const bool use_needle = (sds->vector_draw_type == VECTOR_DRAW_NEEDLE); + int line_count = (use_needle) ? 6 : 1; + int slice_axis = -1; + line_count *= sds->res[0] * sds->res[1] * sds->res[2]; + + if (sds->slice_method == MOD_SMOKE_SLICE_AXIS_ALIGNED && + sds->axis_slice_method == AXIS_SLICE_SINGLE) + { + float invviewmat[4][4]; + DRW_viewport_matrix_get(invviewmat, DRW_MAT_VIEWINV); + + const int axis = (sds->slice_axis == SLICE_AXIS_AUTO) + ? axis_dominant_v3_single(invviewmat[2]) + : sds->slice_axis - 1; + slice_axis = axis; + line_count /= sds->res[axis]; + } + + GPU_create_smoke_velocity(smd); + + DRWShadingGroup *grp = DRW_shgroup_create(volume_velocity_shader_get(use_needle), psl->non_meshes); + DRW_shgroup_uniform_texture(grp, "velocityX", sds->tex_velocity_x); + DRW_shgroup_uniform_texture(grp, "velocityY", sds->tex_velocity_y); + DRW_shgroup_uniform_texture(grp, "velocityZ", sds->tex_velocity_z); + DRW_shgroup_uniform_float_copy(grp, "displaySize", sds->vector_scale); + DRW_shgroup_uniform_float_copy(grp, "slicePosition", sds->slice_depth); + DRW_shgroup_uniform_int_copy(grp, "sliceAxis", slice_axis); + DRW_shgroup_call_procedural_lines_add(grp, line_count, ob->obmat); + + BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(smd)); +} + +static void volumes_free_smoke_textures(void) +{ + /* Free Smoke Textures after rendering */ + /* XXX This is a waste of processing and GPU bandwidth if nothing + * is updated. But the problem is since Textures are stored in the + * modifier we don't want them to take precious VRAM if the + * modifier is not used for display. We should share them for + * all viewport in a redraw at least. */ + for (LinkData *link = e_data.smoke_domains.first; link; link = link->next) { + SmokeModifierData *smd = (SmokeModifierData *)link->data; + GPU_free_smoke(smd); + } + BLI_freelistN(&e_data.smoke_domains); +} + +static void DRW_shgroup_gpencil(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer) +{ + float *color; + DRW_object_wire_theme_get(ob, view_layer, &color); + + DRW_shgroup_call_dynamic_add(stl->g_data->gpencil_axes, color, &ob->empty_drawsize, ob->obmat); +} + static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer) { float *color; @@ -1829,9 +1939,9 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl DRW_shgroup_call_procedural_points_add(grp, prb_data->cell_count, NULL); } else if (prb->type == LIGHTPROBE_TYPE_CUBE) { - prb_data->draw_size = prb->data_draw_size * 0.1f; - unit_m4(prb_data->probe_cube_mat); - copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]); + // prb_data->draw_size = prb->data_draw_size * 0.1f; + // unit_m4(prb_data->probe_cube_mat); + // copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]); DRWShadingGroup *grp = shgroup_theme_id_to_probe_cube_outline_shgrp(stl, theme_id); /* TODO remove or change the drawing of the cube probes. Theses line draws nothing on purpose @@ -2081,6 +2191,82 @@ static void DRW_shgroup_texture_space(OBJECT_StorageList *stl, Object *ob, int t DRW_shgroup_call_dynamic_add(stl->g_data->texspace, color, &one, tmp); } +static void DRW_shgroup_bounds(OBJECT_StorageList *stl, Object *ob, int theme_id) +{ + float color[4], center[3], size[3], tmp[4][4], final_mat[4][4], one = 1.0f; + BoundBox bb_local; + + if (ob->type == OB_MBALL && !BKE_mball_is_basis(ob)) { + return; + } + + BoundBox *bb = BKE_object_boundbox_get(ob); + + if (!ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, + OB_MBALL, OB_ARMATURE, OB_LATTICE)) + { + const float min[3] = {-1.0f, -1.0f, -1.0f}, max[3] = {1.0f, 1.0f, 1.0f}; + bb = &bb_local; + BKE_boundbox_init_from_minmax(bb, min, max); + } + + UI_GetThemeColor4fv(theme_id, color); + BKE_boundbox_calc_center_aabb(bb, center); + BKE_boundbox_calc_size_aabb(bb, size); + + switch (ob->boundtype) { + case OB_BOUND_BOX: + size_to_mat4(tmp, size); + copy_v3_v3(tmp[3], center); + mul_m4_m4m4(tmp, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &one, tmp); + break; + case OB_BOUND_SPHERE: + size[0] = max_fff(size[0], size[1], size[2]); + size[1] = size[2] = size[0]; + size_to_mat4(tmp, size); + copy_v3_v3(tmp[3], center); + mul_m4_m4m4(tmp, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->sphere, color, &one, tmp); + break; + case OB_BOUND_CYLINDER: + size[0] = max_ff(size[0], size[1]); + size[1] = size[0]; + size_to_mat4(tmp, size); + copy_v3_v3(tmp[3], center); + mul_m4_m4m4(tmp, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->cylinder, color, &one, tmp); + break; + case OB_BOUND_CONE: + size[0] = max_ff(size[0], size[1]); + size[1] = size[0]; + size_to_mat4(tmp, size); + copy_v3_v3(tmp[3], center); + /* Cone batch has base at 0 and is pointing towards +Y. */ + swap_v3_v3(tmp[1], tmp[2]); + tmp[3][2] -= size[2]; + mul_m4_m4m4(tmp, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->cone, color, &one, tmp); + break; + case OB_BOUND_CAPSULE: + size[0] = max_ff(size[0], size[1]); + size[1] = size[0]; + scale_m4_fl(tmp, size[0]); + copy_v2_v2(tmp[3], center); + tmp[3][2] = center[2] + max_ff(0.0f, size[2] - size[0]); + mul_m4_m4m4(final_mat, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->capsule_cap, color, &one, final_mat); + negate_v3(tmp[2]); + tmp[3][2] = center[2] - max_ff(0.0f, size[2] - size[0]); + mul_m4_m4m4(final_mat, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->capsule_cap, color, &one, final_mat); + tmp[2][2] = max_ff(0.0f, size[2] * 2.0f - size[0] * 2.0f); + mul_m4_m4m4(final_mat, ob->obmat, tmp); + DRW_shgroup_call_dynamic_add(stl->g_data->capsule_body, color, &one, final_mat); + break; + } +} + static void OBJECT_cache_populate_particles(Object *ob, OBJECT_PassList *psl) { @@ -2099,7 +2285,7 @@ static void OBJECT_cache_populate_particles(Object *ob, unit_m4(mat); if (draw_as != PART_DRAW_PATH) { - struct Gwn_Batch *geom = DRW_cache_particles_get_dots(ob, psys); + struct GPUBatch *geom = DRW_cache_particles_get_dots(ob, psys); DRWShadingGroup *shgrp = NULL; static int screen_space[2] = {0, 1}; static float def_prim_col[3] = {0.5f, 0.5f, 0.5f}; @@ -2162,7 +2348,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); ViewLayer *view_layer = draw_ctx->view_layer; + Scene *scene = draw_ctx->scene; View3D *v3d = draw_ctx->v3d; + ModifierData *md = NULL; int theme_id = TH_UNDEFINED; /* Handle particles first in case the emitter itself shouldn't be rendered. */ @@ -2174,15 +2362,15 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) return; } - bool do_outlines = (draw_ctx->v3d->flag & V3D_SELECT_OUTLINE) && ((ob->base_flag & BASE_SELECTED) != 0); - bool show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0); + const bool do_outlines = (draw_ctx->v3d->flag & V3D_SELECT_OUTLINE) && ((ob->base_flag & BASE_SELECTED) != 0); + const bool show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0); const bool hide_object_extra = (v3d->overlay.flag & V3D_OVERLAY_HIDE_OBJECT_XTRAS) != 0; if (do_outlines) { if ((ob != draw_ctx->object_edit) && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) { - struct Gwn_Batch *geom; + struct GPUBatch *geom; const bool xray_enabled = ((v3d->shading.flag & V3D_SHADING_XRAY) != 0) && - (v3d->drawtype < OB_MATERIAL); + (v3d->shading.type < OB_MATERIAL); if (xray_enabled) { geom = DRW_cache_object_edge_detection_get(ob, NULL); } @@ -2208,7 +2396,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if (ob != draw_ctx->object_edit) { Mesh *me = ob->data; if (me->totedge == 0) { - struct Gwn_Batch *geom = DRW_cache_mesh_verts_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_verts_get(ob); if (geom) { if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); @@ -2219,7 +2407,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) } } else { - struct Gwn_Batch *geom = DRW_cache_mesh_loose_edges_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_loose_edges_get(ob); if (geom) { if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); @@ -2240,7 +2428,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if (hide_object_extra) { break; } - struct Gwn_Batch *geom = DRW_cache_lattice_wire_get(ob, false); + struct GPUBatch *geom = DRW_cache_lattice_wire_get(ob, false); if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); } @@ -2256,7 +2444,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if (hide_object_extra) { break; } - struct Gwn_Batch *geom = DRW_cache_curve_edge_wire_get(ob); + struct GPUBatch *geom = DRW_cache_curve_edge_wire_get(ob); if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); } @@ -2290,6 +2478,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) } DRW_shgroup_empty(stl, psl, ob, view_layer); break; + case OB_GPENCIL: + DRW_shgroup_gpencil(stl, ob, view_layer); + break; case OB_SPEAKER: if (hide_object_extra) { break; @@ -2333,8 +2524,9 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) /* don't show object extras in set's */ if ((ob->base_flag & (BASE_FROM_SET | BASE_FROMDUPLI)) == 0) { - - DRW_shgroup_object_center(stl, ob, view_layer, v3d); + if ((draw_ctx->object_mode & OB_MODE_ALL_PAINT) == 0) { + DRW_shgroup_object_center(stl, ob, view_layer, v3d); + } if (show_relations) { DRW_shgroup_relationship_lines(stl, ob); @@ -2359,6 +2551,17 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if ((ob->dtx & OB_TEXSPACE) && ELEM(ob->type, OB_MESH, OB_CURVE, OB_MBALL)) { DRW_shgroup_texture_space(stl, ob, theme_id); } + + if (ob->dtx & OB_DRAWBOUNDOX) { + DRW_shgroup_bounds(stl, ob, theme_id); + } + + if ((md = modifiers_findByType(ob, eModifierType_Smoke)) && + (modifier_isEnabled(scene, md, eModifierMode_Realtime)) && + (((SmokeModifierData *)md)->domain != NULL)) + { + DRW_shgroup_volume_extra(psl, stl, ob, view_layer, scene, md); + } } } @@ -2458,6 +2661,8 @@ static void OBJECT_draw_scene(void *vedata) BLI_ghash_free(stl->g_data->image_plane_map, NULL, MEM_freeN); stl->g_data->image_plane_map = NULL; } + + volumes_free_smoke_textures(); } static const DrawEngineDataSize OBJECT_data_size = DRW_VIEWPORT_DATA_SIZE(OBJECT_Data); diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c index a67c7ffb131..e3c986bde5a 100644 --- a/source/blender/draw/modes/overlay_mode.c +++ b/source/blender/draw/modes/overlay_mode.c @@ -175,7 +175,7 @@ static void overlay_cache_populate(void *vedata, Object *ob) return; if (stl->g_data->overlay.flag & V3D_OVERLAY_FACE_ORIENTATION) { - struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { DRW_shgroup_call_add(pd->face_orientation_shgrp, geom, ob->obmat); } diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c index 85cff28b313..cf8e520323e 100644 --- a/source/blender/draw/modes/paint_texture_mode.c +++ b/source/blender/draw/modes/paint_texture_mode.c @@ -227,6 +227,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata) DRWShadingGroup *grp = DRW_shgroup_create(e_data.image_sh, psl->image_faces); DRW_shgroup_uniform_texture(grp, "image", tex); DRW_shgroup_uniform_float(grp, "alpha", &draw_ctx->v3d->overlay.texture_paint_mode_opacity, 1); + DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo); stl->g_data->shgroup_image_array[i] = grp; } else { @@ -259,6 +260,7 @@ static void PAINT_TEXTURE_cache_init(void *vedata) DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay); + DRW_shgroup_uniform_block(stl->g_data->lwire_shgrp, "globalsBlock", globals_ubo); } { @@ -293,9 +295,9 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob) if (use_surface) { if (me->mloopuv != NULL) { if (use_material_slots) { - struct Gwn_Batch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL; + struct GPUBatch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL; if ((me->totcol == 0) || (geom_array == NULL)) { - struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_surface_get(ob); DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat); ok = true; } @@ -312,7 +314,7 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob) } } else { - struct Gwn_Batch *geom = DRW_cache_mesh_surface_texpaint_single_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_surface_texpaint_single_get(ob); if (geom && stl->g_data->shgroup_image_array[0]) { DRW_shgroup_call_add(stl->g_data->shgroup_image_array[0], geom, ob->obmat); ok = true; @@ -321,7 +323,7 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob) } if (!ok) { - struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob); + struct GPUBatch *geom = DRW_cache_mesh_surface_get(ob); DRW_shgroup_call_add(stl->g_data->shgroup_fallback, geom, ob->obmat); } } @@ -329,7 +331,7 @@ static void PAINT_TEXTURE_cache_populate(void *vedata, Object *ob) /* Face Mask */ const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; if (use_face_sel) { - struct Gwn_Batch *geom; + struct GPUBatch *geom; /* Note: ideally selected faces wouldn't show interior wire. */ const bool use_wire = true; geom = DRW_cache_mesh_edges_paint_overlay_get(ob, use_wire, use_face_sel); diff --git a/source/blender/draw/modes/paint_vertex_mode.c b/source/blender/draw/modes/paint_vertex_mode.c index 9cf6ea52d33..236f76367d4 100644 --- a/source/blender/draw/modes/paint_vertex_mode.c +++ b/source/blender/draw/modes/paint_vertex_mode.c @@ -36,6 +36,8 @@ #include "DNA_mesh_types.h" #include "DNA_view3d_types.h" +#include "DEG_depsgraph_query.h" + extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ extern struct GlobalsUboStorage ts; /* draw_common.c */ @@ -125,6 +127,7 @@ static void PAINT_VERTEX_cache_init(void *vedata) DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay); + DRW_shgroup_uniform_block(stl->g_data->lwire_shgrp, "globalsBlock", globals_ubo); } { @@ -146,11 +149,13 @@ static void PAINT_VERTEX_cache_populate(void *vedata, Object *ob) const View3D *v3d = draw_ctx->v3d; if ((ob->type == OB_MESH) && (ob == draw_ctx->obact)) { + /* We're always painting on original, display original data. */ + ob = DEG_get_original_object(ob); const Mesh *me = ob->data; const bool use_wire = (v3d->overlay.paint_flag & V3D_OVERLAY_PAINT_WIRE) != 0; const bool use_surface = v3d->overlay.vertex_paint_mode_opacity != 0.0f; const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; - struct Gwn_Batch *geom; + struct GPUBatch *geom; if (use_surface) { geom = DRW_cache_mesh_surface_vert_colors_get(ob); diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c index 14fae743d8c..3bbe8911491 100644 --- a/source/blender/draw/modes/paint_weight_mode.c +++ b/source/blender/draw/modes/paint_weight_mode.c @@ -154,6 +154,7 @@ static void PAINT_WEIGHT_cache_init(void *vedata) DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.wire_overlay_shader, psl->wire_overlay); + DRW_shgroup_uniform_block(stl->g_data->lwire_shgrp, "globalsBlock", globals_ubo); } { @@ -173,6 +174,7 @@ static void PAINT_WEIGHT_cache_init(void *vedata) DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL); stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.vert_overlay_shader, psl->vert_overlay); + DRW_shgroup_uniform_block(stl->g_data->vert_shgrp, "globalsBlock", globals_ubo); } } @@ -190,7 +192,7 @@ static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob) const bool use_surface = v3d->overlay.weight_paint_mode_opacity != 0.0f; const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; - struct Gwn_Batch *geom; + struct GPUBatch *geom; if (use_surface) { geom = DRW_cache_mesh_surface_weights_get(ob); diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c index 19c3ddd4b50..f4879483540 100644 --- a/source/blender/draw/modes/particle_mode.c +++ b/source/blender/draw/modes/particle_mode.c @@ -148,17 +148,17 @@ static void particle_edit_cache_populate(void *vedata, const DRWContextState *draw_ctx = DRW_context_state_get(); ParticleEditSettings *pset = PE_settings(draw_ctx->scene); { - struct Gwn_Batch *strands = + struct GPUBatch *strands = DRW_cache_particles_get_edit_strands(object, psys, edit); DRW_shgroup_call_add(stl->g_data->strands_group, strands, NULL); } if (pset->selectmode == SCE_SELECT_POINT) { - struct Gwn_Batch *points = + struct GPUBatch *points = DRW_cache_particles_get_edit_inner_points(object, psys, edit); DRW_shgroup_call_add(stl->g_data->inner_points_group, points, NULL); } if (ELEM(pset->selectmode, SCE_SELECT_POINT, SCE_SELECT_END)) { - struct Gwn_Batch *points = + struct GPUBatch *points = DRW_cache_particles_get_edit_tip_points(object, psys, edit); DRW_shgroup_call_add(stl->g_data->tip_points_group, points, NULL); } diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c index 57efc65542c..7a4abcac179 100644 --- a/source/blender/draw/modes/pose_mode.c +++ b/source/blender/draw/modes/pose_mode.c @@ -75,6 +75,7 @@ typedef struct POSE_PrivateData { DRWShadingGroup *bone_selection_invert_shgrp; float blend_color[4]; float blend_color_invert[4]; + bool transparent_bones; } POSE_PrivateData; /* Transient data */ static struct { @@ -112,9 +113,10 @@ static void POSE_cache_init(void *vedata) if (!stl->g_data) { /* Alloc transient pointers */ - stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); + stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__); } POSE_PrivateData *ppd = stl->g_data; + ppd->transparent_bones = (draw_ctx->v3d->overlay.arm_flag & V3D_OVERLAY_ARM_TRANSP_BONES) != 0; { /* Solid bones */ @@ -195,7 +197,7 @@ static bool POSE_is_driven_by_active_armature(Object *ob) static void POSE_cache_populate(void *vedata, Object *ob) { POSE_PassList *psl = ((POSE_Data *)vedata)->psl; - POSE_StorageList *stl = ((POSE_Data *)vedata)->stl; + POSE_PrivateData *ppd = ((POSE_Data *)vedata)->stl->g_data; const DRWContextState *draw_ctx = DRW_context_state_get(); /* In the future this will allow us to implement face gizmos, @@ -214,20 +216,20 @@ static void POSE_cache_populate(void *vedata, Object *ob) .bone_axes = psl->bone_axes, .relationship_lines = psl->relationship, }; - DRW_shgroup_armature_pose(ob, passes); + DRW_shgroup_armature_pose(ob, passes, ppd->transparent_bones); } } else if (ob->type == OB_MESH && !DRW_state_is_select() && POSE_is_bone_selection_overlay_active()) { - struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { if (POSE_is_driven_by_active_armature(ob)) { - DRW_shgroup_call_object_add(stl->g_data->bone_selection_shgrp, geom, ob); + DRW_shgroup_call_object_add(ppd->bone_selection_shgrp, geom, ob); } else { - DRW_shgroup_call_object_add(stl->g_data->bone_selection_invert_shgrp, geom, ob); + DRW_shgroup_call_object_add(ppd->bone_selection_invert_shgrp, geom, ob); } } } diff --git a/source/blender/draw/modes/shaders/armature_envelope_solid_frag.glsl b/source/blender/draw/modes/shaders/armature_envelope_solid_frag.glsl index b20656ff326..78b29296601 100644 --- a/source/blender/draw/modes/shaders/armature_envelope_solid_frag.glsl +++ b/source/blender/draw/modes/shaders/armature_envelope_solid_frag.glsl @@ -1,4 +1,6 @@ +uniform float alpha = 0.6; + flat in vec3 finalStateColor; flat in vec3 finalBoneColor; in vec3 normalView; @@ -12,5 +14,5 @@ void main() float n = normalize(normalView).z; float fac = clamp((n * (1.0 - s)) + s, 0.0, 1.0); fragColor.rgb = mix(finalStateColor, finalBoneColor, fac); - fragColor.a = 0.6; /* Hardcoded transparency factor. */ + fragColor.a = alpha; } diff --git a/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl b/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl index 89f4d97f29b..45748bf5644 100644 --- a/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl +++ b/source/blender/draw/modes/shaders/armature_shape_solid_frag.glsl @@ -1,9 +1,11 @@ +uniform float alpha = 0.6; + in vec4 finalColor; out vec4 fragColor; void main() { - fragColor = vec4(finalColor.rgb, 0.6); /* Hardcoded transparency factor. */ + fragColor = vec4(finalColor.rgb, alpha); } diff --git a/source/blender/draw/modes/shaders/armature_sphere_solid_frag.glsl b/source/blender/draw/modes/shaders/armature_sphere_solid_frag.glsl index 3c80f629d79..a0fdd55931f 100644 --- a/source/blender/draw/modes/shaders/armature_sphere_solid_frag.glsl +++ b/source/blender/draw/modes/shaders/armature_sphere_solid_frag.glsl @@ -3,6 +3,7 @@ uniform mat4 ViewMatrixInverse; uniform mat4 ProjectionMatrix; +uniform float alpha = 0.4; flat in vec3 finalStateColor; flat in vec3 finalBoneColor; @@ -73,8 +74,7 @@ void main() float dither = (0.5 + dot(vec2(ivec2(gl_FragCoord.xy) & ivec2(1)), vec2(1.0, 2.0))) * 0.25; dither *= (1.0 / 255.0); /* Assume 8bit per color buffer. */ - /* Hardcoded transparency factor. Less than shape to be less distractive. */ - fragColor = vec4(fragColor.rgb + dither, 0.4); + fragColor = vec4(fragColor.rgb + dither, alpha); t /= ray_len; gl_FragDepth = get_depth_from_view_z(ray_dir_view.z * t + ray_ori_view.z); diff --git a/source/blender/draw/modes/shaders/volume_velocity_vert.glsl b/source/blender/draw/modes/shaders/volume_velocity_vert.glsl new file mode 100644 index 00000000000..574c434920e --- /dev/null +++ b/source/blender/draw/modes/shaders/volume_velocity_vert.glsl @@ -0,0 +1,115 @@ + +uniform mat4 ModelViewProjectionMatrix; + +uniform sampler3D velocityX; +uniform sampler3D velocityY; +uniform sampler3D velocityZ; +uniform float displaySize = 1.0; +uniform float slicePosition; +uniform int sliceAxis; /* -1 is no slice, 0 is X, 1 is Y, 2 is Z. */ + +flat out vec4 finalColor; + +const vec3 corners[4] = vec3[4]( + vec3(0.0, 0.2, -0.5), + vec3(-0.2 * 0.866, -0.2 * 0.5, -0.5), + vec3(0.2 * 0.866, -0.2 * 0.5, -0.5), + vec3(0.0, 0.0, 0.5) +); + +const int indices[12] = int[12](0, 1, 1, 2, 2, 0, 0, 3, 1, 3, 2, 3); + +/* Straight Port from BKE_defvert_weight_to_rgb() + * TODO port this to a color ramp. */ +vec3 weight_to_color(float weight) +{ + vec3 r_rgb = vec3(0.0); + float blend = ((weight / 2.0) + 0.5); + + if (weight <= 0.25) { /* blue->cyan */ + r_rgb.g = blend * weight * 4.0; + r_rgb.b = blend; + } + else if (weight <= 0.50) { /* cyan->green */ + r_rgb.g = blend; + r_rgb.b = blend * (1.0 - ((weight - 0.25) * 4.0)); + } + else if (weight <= 0.75) { /* green->yellow */ + r_rgb.r = blend * ((weight - 0.50) * 4.0); + r_rgb.g = blend; + } + else if (weight <= 1.0) { /* yellow->red */ + r_rgb.r = blend; + r_rgb.g = blend * (1.0 - ((weight - 0.75) * 4.0)); + } + else { + /* exceptional value, unclamped or nan, + * avoid uninitialized memory use */ + r_rgb = vec3(1.0, 0.0, 1.0); + } + + return r_rgb; +} + +mat3 rotation_from_vector(vec3 v) +{ + /* Add epsilon to avoid NaN. */ + vec3 N = normalize(v + 1e-8); + vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0,0.0,1.0) : vec3(1.0,0.0,0.0); + vec3 T = normalize(cross(UpVector, N)); + vec3 B = cross(N, T); + return mat3(T, B, N); +} + +void main() +{ +#ifdef USE_NEEDLE + int cell = gl_VertexID / 12; +#else + int cell = gl_VertexID / 2; +#endif + + ivec3 volume_size = textureSize(velocityX, 0); + float voxel_size = 1.0 / float(max(max(volume_size.x, volume_size.y), volume_size.z)); + + ivec3 cell_ofs = ivec3(0); + ivec3 cell_div = volume_size; + if (sliceAxis == 0) { + cell_ofs.x = int(slicePosition * float(volume_size.x)); + cell_div.x = 1; + } + else if (sliceAxis == 1) { + cell_ofs.y = int(slicePosition * float(volume_size.y)); + cell_div.y = 1; + } + else if (sliceAxis == 2) { + cell_ofs.z = int(slicePosition * float(volume_size.z)); + cell_div.z = 1; + } + + ivec3 cell_co; + cell_co.x = cell % cell_div.x; + cell_co.y = (cell / cell_div.x) % cell_div.y; + cell_co.z = cell / (cell_div.x * cell_div.y); + cell_co += cell_ofs; + + vec3 pos = (vec3(cell_co) + 0.5) / vec3(volume_size); + pos = pos * 2.0 - 1.0; + + vec3 velocity; + velocity.x = texelFetch(velocityX, cell_co, 0).r; + velocity.y = texelFetch(velocityY, cell_co, 0).r; + velocity.z = texelFetch(velocityZ, cell_co, 0).r; + + finalColor = vec4(weight_to_color(length(velocity)), 1.0); + +#ifdef USE_NEEDLE + mat3 rot_mat = rotation_from_vector(velocity); + vec3 rotated_pos = rot_mat * corners[indices[gl_VertexID % 12]]; + pos += rotated_pos * length(velocity) * displaySize * voxel_size; +#else + pos += (((gl_VertexID % 2) == 1) ? velocity : vec3(0.0)) * displaySize * voxel_size; +#endif + + gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0); +} |