Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenfont/intern/blf_font.c6
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h3
-rw-r--r--source/blender/blenkernel/BKE_mesh_runtime.h7
-rw-r--r--source/blender/blenkernel/BKE_paint.h2
-rw-r--r--source/blender/blenkernel/BKE_scene.h4
-rw-r--r--source/blender/blenkernel/CMakeLists.txt6
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c25
-rw-r--r--source/blender/blenkernel/intern/blender.c6
-rw-r--r--source/blender/blenkernel/intern/cloth.c13
-rw-r--r--source/blender/blenkernel/intern/constraint.c8
-rw-r--r--source/blender/blenkernel/intern/gpencil.c1
-rw-r--r--source/blender/blenkernel/intern/mball.c58
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c10
-rw-r--r--source/blender/blenkernel/intern/paint.c10
-rw-r--r--source/blender/blenkernel/intern/pointcache.c5
-rw-r--r--source/blender/blenkernel/intern/scene.c29
-rw-r--r--source/blender/blenkernel/intern/seqcache.c1
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c67
-rw-r--r--source/blender/blenkernel/intern/seqprefetch.c4
-rw-r--r--source/blender/blenkernel/intern/sequencer.c4
-rw-r--r--source/blender/blenkernel/intern/unit.c1
-rw-r--r--source/blender/blenlib/BLI_compiler_compat.h1
-rw-r--r--source/blender/blenlib/BLI_listbase.h9
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c39
-rw-r--r--source/blender/blenlib/intern/freetypefont.c3
-rw-r--r--source/blender/blenloader/BLO_readfile.h3
-rw-r--r--source/blender/blenloader/CMakeLists.txt2
-rw-r--r--source/blender/blenloader/intern/versioning_290.c24
-rw-r--r--source/blender/blenloader/intern/versioning_userdef.c20
-rw-r--r--source/blender/blenloader/tests/blendfile_loading_base_test.cc2
-rw-r--r--source/blender/blenloader/tests/blendfile_loading_base_test.h4
-rw-r--r--source/blender/bmesh/CMakeLists.txt4
-rw-r--r--source/blender/compositor/COM_compositor.h1
-rw-r--r--source/blender/depsgraph/CMakeLists.txt4
-rw-r--r--source/blender/depsgraph/DEG_depsgraph.h13
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_build.h33
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_query.h3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc4
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline.cc11
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline.h2
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_all_objects.cc77
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_all_objects.h44
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_compositor.cc5
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_compositor.h3
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_from_ids.cc44
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_from_ids.h6
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_render.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_render.h2
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_view_layer.cc7
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_view_layer.h2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc39
-rw-r--r--source/blender/depsgraph/intern/depsgraph_debug.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_eval.cc14
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc4
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc4
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc5
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.h2
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_time.h6
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c77
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h5
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c5
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c20
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl2
-rw-r--r--source/blender/draw/engines/workbench/workbench_shader.c34
-rw-r--r--source/blender/draw/intern/DRW_render.h52
-rw-r--r--source/blender/draw/intern/draw_common.c1
-rw-r--r--source/blender/draw/intern/draw_common.h3
-rw-r--r--source/blender/draw/intern/draw_manager.c13
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c442
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c45
-rw-r--r--source/blender/draw/intern/draw_view.c4
-rw-r--r--source/blender/draw/intern/shaders/common_globals_lib.glsl3
-rw-r--r--source/blender/draw/intern/smaa_textures.h1
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c6
-rw-r--r--source/blender/editors/animation/anim_draw.c12
-rw-r--r--source/blender/editors/animation/anim_markers.c12
-rw-r--r--source/blender/editors/animation/anim_motion_paths.c12
-rw-r--r--source/blender/editors/animation/keyframes_draw.c4
-rw-r--r--source/blender/editors/animation/time_scrub_ui.c6
-rw-r--r--source/blender/editors/curve/editcurve_paint.c8
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c8
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c12
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c8
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c8
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c4
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c12
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c8
-rw-r--r--source/blender/editors/gpencil/annotate_draw.c8
-rw-r--r--source/blender/editors/gpencil/annotate_paint.c10
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c5
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_mesh.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c6
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c14
-rw-r--r--source/blender/editors/include/ED_info.h9
-rw-r--r--source/blender/editors/include/ED_screen.h4
-rw-r--r--source/blender/editors/include/ED_sculpt.h4
-rw-r--r--source/blender/editors/include/UI_view2d.h4
-rw-r--r--source/blender/editors/interface/interface.c83
-rw-r--r--source/blender/editors/interface/interface_align.c10
-rw-r--r--source/blender/editors/interface/interface_context_menu.c7
-rw-r--r--source/blender/editors/interface/interface_draw.c143
-rw-r--r--source/blender/editors/interface/interface_handlers.c125
-rw-r--r--source/blender/editors/interface/interface_icons.c26
-rw-r--r--source/blender/editors/interface/interface_layout.c107
-rw-r--r--source/blender/editors/interface/interface_ops.c24
-rw-r--r--source/blender/editors/interface/interface_panel.c22
-rw-r--r--source/blender/editors/interface/interface_query.c12
-rw-r--r--source/blender/editors/interface/interface_region_color_picker.c7
-rw-r--r--source/blender/editors/interface/interface_region_menu_popup.c37
-rw-r--r--source/blender/editors/interface/interface_region_popover.c21
-rw-r--r--source/blender/editors/interface/interface_region_popup.c32
-rw-r--r--source/blender/editors/interface/interface_region_search.c24
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c12
-rw-r--r--source/blender/editors/interface/interface_style.c23
-rw-r--r--source/blender/editors/interface/interface_templates.c25
-rw-r--r--source/blender/editors/interface/interface_utils.c37
-rw-r--r--source/blender/editors/interface/interface_widgets.c115
-rw-r--r--source/blender/editors/interface/view2d.c6
-rw-r--r--source/blender/editors/interface/view2d_ops.c4
-rw-r--r--source/blender/editors/io/io_usd.c10
-rw-r--r--source/blender/editors/mask/mask_draw.c11
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c6
-rw-r--r--source/blender/editors/mesh/editmesh_mask_extract.c16
-rw-r--r--source/blender/editors/object/object_bake_api.c2
-rw-r--r--source/blender/editors/object/object_constraint.c41
-rw-r--r--source/blender/editors/object/object_modifier.c2
-rw-r--r--source/blender/editors/object/object_remesh.c4
-rw-r--r--source/blender/editors/physics/particle_edit.c4
-rw-r--r--source/blender/editors/render/render_opengl.c8
-rw-r--r--source/blender/editors/scene/scene_edit.c2
-rw-r--r--source/blender/editors/screen/area.c334
-rw-r--r--source/blender/editors/screen/screen_draw.c25
-rw-r--r--source/blender/editors/screen/screen_edit.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c29
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c27
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c18
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c40
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_boundary.c337
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c289
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c51
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_color.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c148
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h73
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c5
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c88
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_transform.c2
-rw-r--r--source/blender/editors/sound/sound_ops.c5
-rw-r--r--source/blender/editors/space_action/action_draw.c8
-rw-r--r--source/blender/editors/space_buttons/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c8
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c8
-rw-r--r--source/blender/editors/space_clip/clip_draw.c18
-rw-r--r--source/blender/editors/space_clip/clip_graph_draw.c4
-rw-r--r--source/blender/editors/space_clip/clip_utils.c6
-rw-r--r--source/blender/editors/space_file/file_draw.c10
-rw-r--r--source/blender/editors/space_graph/graph_draw.c26
-rw-r--r--source/blender/editors/space_graph/space_graph.c8
-rw-r--r--source/blender/editors/space_image/image_draw.c36
-rw-r--r--source/blender/editors/space_info/info_stats.c33
-rw-r--r--source/blender/editors/space_info/textview.c10
-rw-r--r--source/blender/editors/space_nla/nla_draw.c26
-rw-r--r--source/blender/editors/space_node/drawnode.c20
-rw-r--r--source/blender/editors/space_node/node_draw.c116
-rw-r--r--source/blender/editors/space_node/node_edit.c5
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c29
-rw-r--r--source/blender/editors/space_script/script_edit.c6
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c84
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c6
-rw-r--r--source/blender/editors/space_text/text_draw.c10
-rw-r--r--source/blender/editors/space_text/text_ops.c3
-rw-r--r--source/blender/editors/space_view3d/drawobject.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c20
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c32
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_ruler.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_placement.c12
-rw-r--r--source/blender/editors/transform/transform.c6
-rw-r--r--source/blender/editors/transform/transform_constraints.c2
-rw-r--r--source/blender/editors/transform/transform_convert_object.c2
-rw-r--r--source/blender/editors/transform/transform_draw_cursors.c4
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c4
-rw-r--r--source/blender/editors/transform/transform_mode_edge_slide.c6
-rw-r--r--source/blender/editors/transform/transform_mode_vert_slide.c4
-rw-r--r--source/blender/editors/transform/transform_snap.c4
-rw-r--r--source/blender/editors/util/numinput.c6
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c27
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c4
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp3
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp2
-rw-r--r--source/blender/freestyle/intern/system/PythonInterpreter.h10
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c9
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c9
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c9
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c9
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c9
-rw-r--r--source/blender/gpu/CMakeLists.txt7
-rw-r--r--source/blender/gpu/GPU_batch.h30
-rw-r--r--source/blender/gpu/GPU_framebuffer.h1
-rw-r--r--source/blender/gpu/GPU_material.h9
-rw-r--r--source/blender/gpu/GPU_matrix.h4
-rw-r--r--source/blender/gpu/GPU_shader.h28
-rw-r--r--source/blender/gpu/GPU_state.h148
-rw-r--r--source/blender/gpu/intern/gpu_backend.hh6
-rw-r--r--source/blender/gpu/intern/gpu_batch.cc88
-rw-r--r--source/blender/gpu/intern/gpu_batch_presets.c1
-rw-r--r--source/blender/gpu/intern/gpu_batch_utils.c1
-rw-r--r--source/blender/gpu/intern/gpu_context.cc1
-rw-r--r--source/blender/gpu/intern/gpu_context_private.hh3
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.cc51
-rw-r--r--source/blender/gpu/intern/gpu_immediate.cc15
-rw-r--r--source/blender/gpu/intern/gpu_matrix.cc22
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c15
-rw-r--r--source/blender/gpu/intern/gpu_select_sample_query.c26
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc698
-rw-r--r--source/blender/gpu/intern/gpu_shader_builtin.c2
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.hh63
-rw-r--r--source/blender/gpu/intern/gpu_state.cc482
-rw-r--r--source/blender/gpu/intern/gpu_state_private.hh167
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc7
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc117
-rw-r--r--source/blender/gpu/opengl/gl_backend.hh6
-rw-r--r--source/blender/gpu/opengl/gl_batch.cc5
-rw-r--r--source/blender/gpu/opengl/gl_context.cc4
-rw-r--r--source/blender/gpu/opengl/gl_drawlist.cc9
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc443
-rw-r--r--source/blender/gpu/opengl/gl_shader.hh81
-rw-r--r--source/blender/gpu/opengl/gl_state.cc423
-rw-r--r--source/blender/gpu/opengl/gl_state.hh63
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl3
-rw-r--r--source/blender/io/alembic/exporter/abc_export_capi.cc17
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_abstract.cc16
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_abstract.h5
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_mesh.cc23
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_transform.cc2
-rw-r--r--source/blender/io/common/IO_abstract_hierarchy_iterator.h4
-rw-r--r--source/blender/io/common/intern/abstract_hierarchy_iterator.cc24
-rw-r--r--source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc49
-rw-r--r--source/blender/io/usd/intern/usd_capi.cc12
-rw-r--r--source/blender/io/usd/intern/usd_writer_abstract.cc14
-rw-r--r--source/blender/io/usd/intern/usd_writer_abstract.h4
-rw-r--r--source/blender/io/usd/intern/usd_writer_mesh.cc27
-rw-r--r--source/blender/io/usd/usd.h1
-rw-r--r--source/blender/makesdna/DNA_brush_types.h9
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h1
-rw-r--r--source/blender/makesdna/DNA_object_types.h2
-rw-r--r--source/blender/makesdna/DNA_scene_defaults.h1
-rw-r--r--source/blender/makesdna/DNA_screen_types.h11
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h7
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt13
-rw-r--r--source/blender/makesrna/intern/makesrna.c8
-rw-r--r--source/blender/makesrna/intern/rna_ID.c18
-rw-r--r--source/blender/makesrna/intern/rna_access_compare_override.c4
-rw-r--r--source/blender/makesrna/intern/rna_armature.c2
-rw-r--r--source/blender/makesrna/intern/rna_brush.c36
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c2
-rw-r--r--source/blender/makesrna/intern/rna_internal.h6
-rw-r--r--source/blender/makesrna/intern/rna_main.c12
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c18
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c16
-rw-r--r--source/blender/makesrna/intern/rna_object.c8
-rw-r--r--source/blender/makesrna/intern/rna_scene.c28
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_screen.c6
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c2
-rw-r--r--source/blender/makesrna/intern/rna_space.c13
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c10
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c2
-rw-r--r--source/blender/python/BPY_extern.h40
-rw-r--r--source/blender/python/BPY_extern_python.h (renamed from source/blender/gpu/intern/gpu_shader_private.h)37
-rw-r--r--source/blender/python/BPY_extern_run.h70
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c2
-rw-r--r--source/blender/python/generic/CMakeLists.txt4
-rw-r--r--source/blender/python/generic/py_capi_utils.c14
-rw-r--r--source/blender/python/generic/py_capi_utils.h1
-rw-r--r--source/blender/python/gpu/gpu_py_shader.c3
-rw-r--r--source/blender/python/intern/CMakeLists.txt1
-rw-r--r--source/blender/python/intern/bpy_interface.c357
-rw-r--r--source/blender/python/intern/bpy_interface_run.c422
-rw-r--r--source/blender/python/mathutils/mathutils_bvhtree.c2
-rw-r--r--source/blender/render/intern/source/external_engine.c13
-rw-r--r--source/blender/render/intern/source/pipeline.c4
-rw-r--r--source/blender/simulation/CMakeLists.txt4
-rw-r--r--source/blender/windowmanager/gizmo/WM_gizmo_types.h2
-rw-r--r--source/blender/windowmanager/intern/wm.c3
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c4
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c12
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c5
-rw-r--r--source/blender/windowmanager/intern/wm_files.c9
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c15
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c3
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c12
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c6
-rw-r--r--source/blender/windowmanager/intern/wm_window.c3
-rw-r--r--source/creator/creator_args.c13
-rw-r--r--source/creator/creator_signals.c2
301 files changed, 5501 insertions, 3862 deletions
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 76829db755c..5724d844089 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -221,9 +221,7 @@ void blf_batch_draw(void)
return;
}
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
#ifndef BLF_STANDALONE
/* We need to flush widget base first to ensure correct ordering. */
@@ -239,7 +237,7 @@ void blf_batch_draw(void)
GPU_batch_uniform_1i(g_batch.batch, "glyph", 0);
GPU_batch_draw(g_batch.batch);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* restart to 1st vertex data pointers */
GPU_vertbuf_attr_get_raw_data(g_batch.verts, g_batch.pos_loc, &g_batch.pos_step);
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 6ea113d8828..231cd0e53c5 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -50,6 +50,9 @@ extern "C" {
/** User readable version string. */
const char *BKE_blender_version_string(void);
+/* Returns true when version cycle is alpha, otherwise (beta, rc) returns false. */
+bool BKE_blender_version_is_alpha(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h
index adb7c357049..267be4f44fd 100644
--- a/source/blender/blenkernel/BKE_mesh_runtime.h
+++ b/source/blender/blenkernel/BKE_mesh_runtime.h
@@ -71,7 +71,7 @@ struct Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph,
struct Object *ob,
const struct CustomData_MeshMasks *dataMask);
-struct Mesh *mesh_create_eval_final_render(struct Depsgraph *depsgraph,
+struct Mesh *mesh_create_eval_final(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,
const struct CustomData_MeshMasks *dataMask);
@@ -82,11 +82,6 @@ struct Mesh *mesh_create_eval_final_index_render(struct Depsgraph *depsgraph,
const struct CustomData_MeshMasks *dataMask,
int index);
-struct Mesh *mesh_create_eval_final_view(struct Depsgraph *depsgraph,
- struct Scene *scene,
- struct Object *ob,
- const struct CustomData_MeshMasks *dataMask);
-
struct Mesh *mesh_create_eval_no_deform(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 7b63a4154fa..b2794e9d9d6 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -338,7 +338,7 @@ typedef struct SculptBoundary {
int num_vertices;
/* Distance from a vertex in the boundary to initial vertex indexed by vertex index, taking into
- * account the lengh of all edges between them. Any vertex that is not in the boundary will have
+ * account the length of all edges between them. Any vertex that is not in the boundary will have
* a distance of 0. */
float *distance;
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 8cd86593873..3ab923f05f6 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -110,6 +110,8 @@ void BKE_toolsettings_free(struct ToolSettings *toolsettings);
struct Scene *BKE_scene_duplicate(struct Main *bmain, struct Scene *sce, eSceneCopyMethod type);
void BKE_scene_groups_relink(struct Scene *sce);
+struct Scene *BKE_scene_find_from_view_layer(const struct Main *bmain,
+ const struct ViewLayer *layer);
struct Scene *BKE_scene_find_from_collection(const struct Main *bmain,
const struct Collection *collection);
@@ -145,7 +147,7 @@ void BKE_scene_update_tag_audio_volume(struct Depsgraph *, struct Scene *scene);
void BKE_scene_graph_update_tagged(struct Depsgraph *depsgraph, struct Main *bmain);
void BKE_scene_graph_evaluated_ensure(struct Depsgraph *depsgraph, struct Main *bmain);
-void BKE_scene_graph_update_for_newframe(struct Depsgraph *depsgraph, struct Main *bmain);
+void BKE_scene_graph_update_for_newframe(struct Depsgraph *depsgraph);
void BKE_scene_view_layer_graph_evaluated_ensure(struct Main *bmain,
struct Scene *scene,
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 0c09d491ca1..6cf72eb09d9 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -36,8 +36,8 @@ set(INC
../makesrna
../modifiers
../nodes
- ../simulation
../shader_fx
+ ../simulation
../render/extern/include
../../../intern/ghost
../../../intern/glew-mx
@@ -366,8 +366,8 @@ set(SRC
BKE_packedFile.h
BKE_paint.h
BKE_particle.h
- BKE_persistent_data_handle.hh
BKE_pbvh.h
+ BKE_persistent_data_handle.hh
BKE_pointcache.h
BKE_pointcloud.h
BKE_report.h
@@ -442,9 +442,9 @@ set(LIB
bf_intern_opensubdiv # Uses stub when disabled.
bf_modifiers
bf_nodes
- bf_simulation
bf_rna
bf_shader_fx
+ bf_simulation
)
if(WITH_BINRELOC)
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 0dc85dfaa18..4f587abd9f0 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -909,8 +909,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
/* Sculpt can skip certain modifiers. */
- MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
- const bool has_multires = (mmd && mmd->sculptlvl != 0);
+ const bool has_multires = BKE_sculpt_multires_active(scene, ob) != NULL;
bool multires_applied = false;
const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !use_render;
const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !use_render;
@@ -1991,7 +1990,7 @@ Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph,
return ob->runtime.mesh_deform_eval;
}
-Mesh *mesh_create_eval_final_render(Depsgraph *depsgraph,
+Mesh *mesh_create_eval_final(Depsgraph *depsgraph,
Scene *scene,
Object *ob,
const CustomData_MeshMasks *dataMask)
@@ -2016,26 +2015,6 @@ Mesh *mesh_create_eval_final_index_render(Depsgraph *depsgraph,
return final;
}
-Mesh *mesh_create_eval_final_view(Depsgraph *depsgraph,
- Scene *scene,
- Object *ob,
- const CustomData_MeshMasks *dataMask)
-{
- Mesh *final;
-
- /* XXX hack
- * psys modifier updates particle state when called during dupli-list generation,
- * which can lead to wrong transforms. This disables particle system modifier execution.
- */
- ob->transflag |= OB_NO_PSYS_UPDATE;
-
- mesh_calc_modifiers(depsgraph, scene, ob, 1, false, dataMask, -1, false, false, NULL, &final);
-
- ob->transflag &= ~OB_NO_PSYS_UPDATE;
-
- return final;
-}
-
Mesh *mesh_create_eval_no_deform(Depsgraph *depsgraph,
Scene *scene,
Object *ob,
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index e8aa13a8beb..1d5c8f76cc5 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -135,6 +135,12 @@ const char *BKE_blender_version_string(void)
return blender_version_string;
}
+bool BKE_blender_version_is_alpha(void)
+{
+ bool is_alpha = STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "alpha");
+ return is_alpha;
+}
+
void BKE_blender_globals_init(void)
{
blender_version_init();
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 027761335b0..24b4b85d0d4 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -1611,7 +1611,6 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
if (use_internal_springs && numpolys > 0) {
BVHTreeFromMesh treedata = {NULL};
unsigned int tar_v_idx;
- BLI_bitmap *verts_used = NULL;
Mesh *tmp_mesh = NULL;
RNG *rng;
@@ -1622,7 +1621,7 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
BKE_mesh_calc_normals(tmp_mesh);
}
- verts_used = BLI_BITMAP_NEW(mvert_num * mvert_num, __func__);
+ EdgeSet *existing_vert_pairs = BLI_edgeset_new("cloth_sewing_edges_graph");
BKE_bvhtree_from_mesh_get(&treedata, tmp_mesh ? tmp_mesh : mesh, BVHTREE_FROM_LOOPTRI, 2);
rng = BLI_rng_new_srandom(0);
@@ -1635,12 +1634,12 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
clmd->sim_parms->internal_spring_max_diversion,
(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_INTERNAL_SPRINGS_NORMAL),
&tar_v_idx)) {
- if (BLI_BITMAP_TEST_BOOL(verts_used, i * mvert_num + tar_v_idx)) {
+ if (BLI_edgeset_haskey(existing_vert_pairs, i, tar_v_idx)) {
+ /* We have already created a spring between these verts! */
continue;
}
- BLI_BITMAP_ENABLE(verts_used, i * mvert_num + tar_v_idx);
- BLI_BITMAP_ENABLE(verts_used, tar_v_idx * mvert_num + i);
+ BLI_edgeset_insert(existing_vert_pairs, i, tar_v_idx);
spring = (ClothSpring *)MEM_callocN(sizeof(ClothSpring), "cloth spring");
@@ -1666,7 +1665,7 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
}
else {
cloth_free_errorsprings(cloth, edgelist, spring_ref);
- MEM_freeN(verts_used);
+ BLI_edgeset_free(existing_vert_pairs);
free_bvhtree_from_mesh(&treedata);
if (tmp_mesh) {
BKE_mesh_free(tmp_mesh);
@@ -1675,7 +1674,7 @@ static int cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
}
}
}
- MEM_freeN(verts_used);
+ BLI_edgeset_free(existing_vert_pairs);
free_bvhtree_from_mesh(&treedata);
if (tmp_mesh) {
BKE_mesh_free(tmp_mesh);
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 047f927ae88..e5a9ee53054 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -6032,7 +6032,7 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
*/
enf = con->enforce;
- /* make copy of worldspace matrix pre-constraint for use with blending later */
+ /* make copy of world-space matrix pre-constraint for use with blending later */
copy_m4_m4(oldmat, cob->matrix);
/* move owner matrix into right space */
@@ -6053,16 +6053,16 @@ void BKE_constraints_solve(struct Depsgraph *depsgraph,
cti->flush_constraint_targets(con, &targets, 1);
}
- /* move owner back into worldspace for next constraint/other business */
+ /* move owner back into world-space for next constraint/other business */
if ((con->flag & CONSTRAINT_SPACEONCE) == 0) {
BKE_constraint_mat_convertspace(
cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD, false);
}
/* Interpolate the enforcement, to blend result of constraint into final owner transform
- * - all this happens in worldspace to prevent any weirdness creeping in
+ * - all this happens in world-space to prevent any weirdness creeping in
* (T26014 and T25725), since some constraints may not convert the solution back to the input
- * space before blending but all are guaranteed to end up in good "worldspace" result.
+ * space before blending but all are guaranteed to end up in good "world-space" result.
*/
/* Note: all kind of stuff here before (caused trouble), much easier to just interpolate,
* or did I miss something? -jahka (r.32105) */
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 09305434289..4f65f8a57ab 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -532,6 +532,7 @@ bGPdata *BKE_gpencil_data_addnew(Main *bmain, const char name[])
gpd->grid.lines = GP_DEFAULT_GRID_LINES; /* Number of lines */
/* Onion-skinning settings (data-block level) */
+ gpd->onion_keytype = -1; /* All by default. */
gpd->onion_flag |= (GP_ONION_GHOST_PREVCOL | GP_ONION_GHOST_NEXTCOL);
gpd->onion_flag |= GP_ONION_FADE;
gpd->onion_mode = GP_ONION_MODE_RELATIVE;
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index de07c96e3f0..d2f7ee68430 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -196,11 +196,11 @@ MetaElem *BKE_mball_element_add(MetaBall *mb, const int type)
return ml;
}
/**
- * Compute bounding box of all MetaElems/MetaBalls.
+ * Compute bounding box of all #MetaElem / #MetaBall
*
- * Bounding box is computed from polygonized surface. Object *ob is
- * basic MetaBall (usually with name Meta). All other MetaBalls (with
- * names Meta.001, Meta.002, etc) are included in this Bounding Box.
+ * Bounding box is computed from polygonized surface. \a ob is
+ * basic meta-balls (with name `Meta` for example). All other meta-ball objects
+ * (with names `Meta.001`, `Meta.002`, etc) are included in this bounding-box.
*/
void BKE_mball_texspace_calc(Object *ob)
{
@@ -298,25 +298,30 @@ float *BKE_mball_make_orco(Object *ob, ListBase *dispbase)
return orcodata;
}
-/* Note on mball basis stuff 2.5x (this is a can of worms)
+/**
+ * \brief Test, if \a ob is a basis meta-ball.
+ *
+ * It test last character of Object ID name. If last character
+ * is digit it return 0, else it return 1.
+ *
+ *
+ * Meta-Ball Basis Notes from Blender-2.5x
+ * =======================================
+ *
+ * This is a can of worms.
+ *
* This really needs a rewrite/refactor its totally broken in anything other then basic cases
- * Multiple Scenes + Set Scenes & mixing mball basis SHOULD work but fails to update the depsgraph
- * on rename and linking into scenes or removal of basis mball.
+ * Multiple Scenes + Set Scenes & mixing meta-ball basis _should_ work but fails to update the
+ * depsgraph on rename and linking into scenes or removal of basis meta-ball.
* So take care when changing this code.
*
- * Main idiot thing here is that the system returns find_basis_mball()
- * objects which fail a is_basis_mball() test.
+ * Main idiot thing here is that the system returns #BKE_mball_basis_find()
+ * objects which fail a #BKE_mball_is_basis() test.
*
- * Not only that but the depsgraph and their areas depend on this behavior!,
+ * Not only that but the depsgraph and their areas depend on this behavior,
* so making small fixes here isn't worth it.
* - Campbell
*/
-
-/** \brief Test, if Object *ob is basic MetaBall.
- *
- * It test last character of Object ID name. If last character
- * is digit it return 0, else it return 1.
- */
bool BKE_mball_is_basis(Object *ob)
{
/* just a quick test */
@@ -378,12 +383,12 @@ bool BKE_mball_is_any_unselected(const MetaBall *mb)
}
/**
- * \brief copy some properties from object to other metaball object with same base name
+ * \brief copy some properties from object to other meta-ball object with same base name
*
- * When some properties (wiresize, threshold, update flags) of metaball are changed, then this
- * properties are copied to all metaballs in same "group" (metaballs with same base name: MBall,
- * MBall.001, MBall.002, etc). The most important is to copy properties to the base metaball,
- * because this metaball influence polygonization of metaballs. */
+ * When some properties (wire-size, threshold, update flags) of meta-ball are changed, then this
+ * properties are copied to all meta-balls in same "group" (meta-balls with same base name:
+ * `MBall`, `MBall.001`, `MBall.002`, etc). The most important is to copy properties to the base
+ * meta-ball, because this meta-ball influence polygonization of meta-balls. */
void BKE_mball_properties_copy(Scene *scene, Object *active_object)
{
Scene *sce_iter = scene;
@@ -397,7 +402,7 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object)
BLI_split_name_num(basisname, &basisnr, active_object->id.name + 2, '.');
/* Pass depsgraph as NULL, which means we will not expand into
- * duplis unlike when we generate the mball. Expanding duplis
+ * duplis unlike when we generate the meta-ball. Expanding duplis
* would not be compatible when editing multiple view layers. */
BKE_scene_base_iter_next(NULL, &iter, &sce_iter, 0, NULL, NULL);
while (BKE_scene_base_iter_next(NULL, &iter, &sce_iter, 1, &base, &ob)) {
@@ -424,12 +429,11 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object)
/** \brief This function finds basic MetaBall.
*
- * Basic MetaBall doesn't include any number at the end of
- * its name. All MetaBalls with same base of name can be
- * blended. MetaBalls with different basic name can't be
- * blended.
+ * Basic meta-ball doesn't include any number at the end of
+ * its name. All meta-balls with same base of name can be
+ * blended. meta-balls with different basic name can't be blended.
*
- * warning!, is_basis_mball() can fail on returned object, see long note above.
+ * \warning #BKE_mball_is_basis() can fail on returned object, see function docs for details.
*/
Object *BKE_mball_basis_find(Scene *scene, Object *basis)
{
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 76a6d23bc8f..9426d09885e 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -1111,15 +1111,7 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, Object
Scene *scene = DEG_get_evaluated_scene(depsgraph);
CustomData_MeshMasks mask = CD_MASK_MESH;
- Mesh *result;
-
- if (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER) {
- result = mesh_create_eval_final_render(depsgraph, scene, &object_for_eval, &mask);
- }
- else {
- result = mesh_create_eval_final_view(depsgraph, scene, &object_for_eval, &mask);
- }
-
+ Mesh *result = mesh_create_eval_final(depsgraph, scene, &object_for_eval, &mask);
return result;
}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 19d5c34ad73..e3c209b60e6 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1421,7 +1421,7 @@ MultiresModifierData *BKE_sculpt_multires_active(Scene *scene, Object *ob)
continue;
}
- if (mmd->sculptlvl > 0) {
+ if (mmd->sculptlvl > 0 && !(mmd->flags & eMultiresModifierFlag_UseSculptBaseMesh)) {
return mmd;
}
@@ -1437,10 +1437,9 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
{
ModifierData *md;
Mesh *me = (Mesh *)ob->data;
- MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
VirtualModifierData virtualModifierData;
- if (mmd || ob->sculpt->bm) {
+ if (ob->sculpt->bm || BKE_sculpt_multires_active(scene, ob)) {
return false;
}
@@ -1458,7 +1457,10 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
continue;
}
if (md->type == eModifierType_Multires && (ob->mode & OB_MODE_SCULPT)) {
- continue;
+ MultiresModifierData *mmd = (MultiresModifierData *)md;
+ if (!(mmd->flags & eMultiresModifierFlag_UseSculptBaseMesh)) {
+ continue;
+ }
}
if (md->type == eModifierType_ShapeKey) {
continue;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 64e642462af..8c5915d3768 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -4025,7 +4025,6 @@ static void ptcache_dt_to_str(char *str, double dtime)
/* if bake is not given run simulations to current frame */
void BKE_ptcache_bake(PTCacheBaker *baker)
{
- Main *bmain = baker->bmain;
Scene *scene = baker->scene;
ViewLayer *view_layer = baker->view_layer;
struct Depsgraph *depsgraph = baker->depsgraph;
@@ -4156,7 +4155,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
stime = ptime = PIL_check_seconds_timer();
for (int fr = CFRA; fr <= endframe; fr += baker->quick_step, CFRA = fr) {
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
if (baker->update_progress) {
float progress = ((float)(CFRA - startframe) / (float)(endframe - startframe));
@@ -4255,7 +4254,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
CFRA = cfrao;
if (bake) { /* already on cfra unless baking */
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
/* TODO: call redraw all windows somehow */
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 7e25e8c96ae..1dc51c9ddae 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1129,6 +1129,17 @@ int BKE_scene_base_iter_next(
return iter->phase;
}
+Scene *BKE_scene_find_from_view_layer(const Main *bmain, const ViewLayer *layer)
+{
+ for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ if (BLI_findindex(&scene->view_layers, layer) != -1) {
+ return scene;
+ }
+ }
+
+ return NULL;
+}
+
Scene *BKE_scene_find_from_collection(const Main *bmain, const Collection *collection)
{
for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
@@ -1485,7 +1496,7 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on
for (int pass = 0; pass < 2; pass++) {
/* (Re-)build dependency graph if needed. */
- DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
+ DEG_graph_relations_update(depsgraph);
/* Uncomment this to check if graph was properly tagged for update. */
// DEG_debug_graph_relations_validate(depsgraph, bmain, scene);
/* Flush editing data if needed. */
@@ -1493,7 +1504,7 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on
/* Update all objects: drivers, matrices, displists, etc. flags set
* by depgraph or manual, no layer check here, gets correct flushed.
*/
- DEG_evaluate_on_refresh(bmain, depsgraph);
+ DEG_evaluate_on_refresh(depsgraph);
/* Update sound system. */
BKE_scene_update_sound(depsgraph, bmain);
/* Notify python about depsgraph update. */
@@ -1512,7 +1523,7 @@ static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool on
* be tagged for an update anyway.
*
* If there are no relations changed by the callback this call will do nothing. */
- DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
+ DEG_graph_relations_update(depsgraph);
}
/* Inform editors about possible changes. */
DEG_ids_check_recalc(bmain, depsgraph, scene, view_layer, false);
@@ -1541,10 +1552,11 @@ void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain)
}
/* applies changes right away, does all sets too */
-void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain)
+void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph)
{
Scene *scene = DEG_get_input_scene(depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
+ Main *bmain = DEG_get_bmain(depsgraph);
/* Keep this first. */
BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_FRAME_CHANGE_PRE);
@@ -1555,7 +1567,7 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain)
*/
BKE_image_editors_update_frame(bmain, scene->r.cfra);
BKE_sound_set_cfra(scene->r.cfra);
- DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
+ DEG_graph_relations_update(depsgraph);
/* Update all objects: drivers, matrices, displists, etc. flags set
* by depgraph or manual, no layer check here, gets correct flushed.
*
@@ -1564,10 +1576,10 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain)
* loose any possible unkeyed changes made by the handler. */
if (pass == 0) {
const float ctime = BKE_scene_frame_get(scene);
- DEG_evaluate_on_framechange(bmain, depsgraph, ctime);
+ DEG_evaluate_on_framechange(depsgraph, ctime);
}
else {
- DEG_evaluate_on_refresh(bmain, depsgraph);
+ DEG_evaluate_on_refresh(depsgraph);
}
/* Update sound system animation. */
BKE_scene_update_sound(depsgraph, bmain);
@@ -1578,7 +1590,7 @@ void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph, Main *bmain)
/* NOTE: Similar to this case in scene_graph_update_tagged(). Need to ensure that
* DEG_ids_clear_recalc() doesn't access freed memory of possibly removed ID. */
- DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
+ DEG_graph_relations_update(depsgraph);
}
/* Inform editors about possible changes. */
@@ -2245,6 +2257,7 @@ static Depsgraph **scene_get_depsgraph_p(Main *bmain,
{
BLI_assert(scene != NULL);
BLI_assert(view_layer != NULL);
+ BLI_assert(BKE_scene_find_from_view_layer(bmain, view_layer) == scene);
/* Make sure hash itself exists. */
if (allocate_ghash_entry) {
BKE_scene_ensure_depsgraph_hash(scene);
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index 3d1f33190dc..7d2858050be 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -1326,6 +1326,7 @@ void BKE_sequencer_cache_put(const SeqRenderData *context,
context = BKE_sequencer_prefetch_get_original_context(context);
scene = context->scene;
seq = BKE_sequencer_prefetch_get_original_sequence(seq, scene);
+ BLI_assert(seq != NULL);
}
/* Prevent reinserting, it breaks cache key linking. */
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index afec9b835a5..c6daecbcee6 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -2387,6 +2387,8 @@ static void copy_transform_effect(Sequence *dst, Sequence *src, const int UNUSED
static void transform_image(int x,
int y,
+ int start_line,
+ int total_lines,
ImBuf *ibuf1,
ImBuf *out,
float scale_x,
@@ -2396,34 +2398,27 @@ static void transform_image(int x,
float rotate,
int interpolation)
{
- int xo, yo, xi, yi;
- float xt, yt, xr, yr;
- float s, c;
-
- xo = x;
- yo = y;
-
/* Rotate */
- s = sinf(rotate);
- c = cosf(rotate);
+ float s = sinf(rotate);
+ float c = cosf(rotate);
- for (yi = 0; yi < yo; yi++) {
- for (xi = 0; xi < xo; xi++) {
+ for (int yi = start_line; yi < start_line + total_lines; yi++) {
+ for (int xi = 0; xi < x; xi++) {
/* translate point */
- xt = xi - translate_x;
- yt = yi - translate_y;
+ float xt = xi - translate_x;
+ float yt = yi - translate_y;
/* rotate point with center ref */
- xr = c * xt + s * yt;
- yr = -s * xt + c * yt;
+ float xr = c * xt + s * yt;
+ float yr = -s * xt + c * yt;
/* scale point with center ref */
xt = xr / scale_x;
yt = yr / scale_y;
/* undo reference center point */
- xt += (xo / 2.0f);
- yt += (yo / 2.0f);
+ xt += (x / 2.0f);
+ yt += (y / 2.0f);
/* interpolate */
switch (interpolation) {
@@ -2441,9 +2436,19 @@ static void transform_image(int x,
}
}
-static void do_transform(
- Scene *scene, Sequence *seq, float UNUSED(facf0), int x, int y, ImBuf *ibuf1, ImBuf *out)
+static void do_transform_effect(const SeqRenderData *context,
+ Sequence *seq,
+ float UNUSED(cfra),
+ float UNUSED(facf0),
+ float UNUSED(facf1),
+ ImBuf *ibuf1,
+ ImBuf *UNUSED(ibuf2),
+ ImBuf *UNUSED(ibuf3),
+ int start_line,
+ int total_lines,
+ ImBuf *out)
{
+ Scene *scene = context->scene;
TransformVars *transform = (TransformVars *)seq->effectdata;
float scale_x, scale_y, translate_x, translate_y, rotate_radians;
@@ -2456,6 +2461,9 @@ static void do_transform(
scale_y = transform->ScaleyIni;
}
+ int x = context->rectx;
+ int y = context->recty;
+
/* Translate */
if (!transform->percent) {
float rd_s = (scene->r.size / 100.0f);
@@ -2473,6 +2481,8 @@ static void do_transform(
transform_image(x,
y,
+ start_line,
+ total_lines,
ibuf1,
out,
scale_x,
@@ -2483,22 +2493,6 @@ static void do_transform(
transform->interpolation);
}
-static ImBuf *do_transform_effect(const SeqRenderData *context,
- Sequence *seq,
- float UNUSED(cfra),
- float facf0,
- float UNUSED(facf1),
- ImBuf *ibuf1,
- ImBuf *ibuf2,
- ImBuf *ibuf3)
-{
- ImBuf *out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3);
-
- do_transform(context->scene, seq, facf0, context->rectx, context->recty, ibuf1, out);
-
- return out;
-}
-
/*********************** Glow *************************/
static void RVBlurBitmap2_float(float *map, int width, int height, float blur, int quality)
@@ -4183,11 +4177,12 @@ static struct SeqEffectHandle get_sequence_effect_impl(int seq_type)
rval.execute = do_glow_effect;
break;
case SEQ_TYPE_TRANSFORM:
+ rval.multithreaded = true;
rval.init = init_transform_effect;
rval.num_inputs = num_inputs_transform;
rval.free = free_transform_effect;
rval.copy = copy_transform_effect;
- rval.execute = do_transform_effect;
+ rval.execute_slice = do_transform_effect;
break;
case SEQ_TYPE_SPEED:
rval.init = init_speed_effect;
diff --git a/source/blender/blenkernel/intern/seqprefetch.c b/source/blender/blenkernel/intern/seqprefetch.c
index 795086fffa4..3a7e4af490a 100644
--- a/source/blender/blenkernel/intern/seqprefetch.c
+++ b/source/blender/blenkernel/intern/seqprefetch.c
@@ -207,7 +207,7 @@ static void seq_prefetch_free_depsgraph(PrefetchJob *pfjob)
static void seq_prefetch_update_depsgraph(PrefetchJob *pfjob)
{
- DEG_evaluate_on_framechange(pfjob->bmain_eval, pfjob->depsgraph, seq_prefetch_cfra(pfjob));
+ DEG_evaluate_on_framechange(pfjob->depsgraph, seq_prefetch_cfra(pfjob));
}
static void seq_prefetch_init_depsgraph(PrefetchJob *pfjob)
@@ -220,7 +220,7 @@ static void seq_prefetch_init_depsgraph(PrefetchJob *pfjob)
DEG_debug_name_set(pfjob->depsgraph, "SEQUENCER PREFETCH");
/* Make sure there is a correct evaluated scene pointer. */
- DEG_graph_build_for_render_pipeline(pfjob->depsgraph, bmain, scene, view_layer);
+ DEG_graph_build_for_render_pipeline(pfjob->depsgraph);
/* Update immediately so we have proper evaluated scene. */
seq_prefetch_update_depsgraph(pfjob);
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index a2a45ae56b3..b4da0c5bd33 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -3593,7 +3593,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context,
/* opengl offscreen render */
depsgraph = BKE_scene_get_depsgraph(context->bmain, scene, view_layer, true);
- BKE_scene_graph_update_for_newframe(depsgraph, context->bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
ibuf = sequencer_view3d_fn(
/* set for OpenGL render (NULL when scrubbing) */
depsgraph,
@@ -3695,7 +3695,7 @@ finally:
scene->r.subframe = orig_data.subframe;
if (is_frame_update && (depsgraph != NULL)) {
- BKE_scene_graph_update_for_newframe(depsgraph, context->bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
#ifdef DURIAN_CAMERA_SWITCH
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index 8414f93ddaa..9b78c9e5fc3 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -757,7 +757,6 @@ static char *find_next_op(const char *str, char *remaining_str, int len_max)
if (ch_is_op(remaining_str[i])) {
if (scientific_notation) {
scientific_notation = false;
- continue;
}
/* Make sure we don't look backwards before the start of the string. */
diff --git a/source/blender/blenlib/BLI_compiler_compat.h b/source/blender/blenlib/BLI_compiler_compat.h
index 0870d01872a..bd8f84cedd6 100644
--- a/source/blender/blenlib/BLI_compiler_compat.h
+++ b/source/blender/blenlib/BLI_compiler_compat.h
@@ -55,4 +55,3 @@ template<typename T> static inline T decltype_helper(T x)
#else
# define BLI_NOINLINE
#endif
-
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index fa7cf7a1847..aff80a2bd86 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -171,6 +171,15 @@ struct LinkData *BLI_genericNodeN(void *data);
#define LISTBASE_FOREACH(type, var, list) \
for (type var = (type)((list)->first); var != NULL; var = (type)(((Link *)(var))->next))
+/**
+ * A version of #LISTBASE_FOREACH that supports incrementing an index variable at every step.
+ * Including this in the macro helps prevent mistakes where "continue" mistakenly skips the
+ * incrementation.
+ */
+#define LISTBASE_FOREACH_INDEX(type, var, list, index_var) \
+ for (type var = (((void)(index_var = 0)), (type)((list)->first)); var != NULL; \
+ var = (type)(((Link *)(var))->next), index_var++)
+
#define LISTBASE_FOREACH_BACKWARD(type, var, list) \
for (type var = (type)((list)->last); var != NULL; var = (type)(((Link *)(var))->prev))
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index f63a523ca60..f030a733752 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -201,6 +201,23 @@ const float bvhtree_kdop_axes[13][3] = {
{0, 1.0, -1.0},
};
+/* Used to correct the epsilon and thus match the overlap distance. */
+const float bvhtree_kdop_axes_length[13] = {
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 1.7320508075688772f,
+ 1.7320508075688772f,
+ 1.7320508075688772f,
+ 1.7320508075688772f,
+ 1.4142135623730951f,
+ 1.4142135623730951f,
+ 1.4142135623730951f,
+ 1.4142135623730951f,
+ 1.4142135623730951f,
+ 1.4142135623730951f,
+};
+
/* -------------------------------------------------------------------- */
/** \name Utility Functions
* \{ */
@@ -970,9 +987,18 @@ void BLI_bvhtree_balance(BVHTree *tree)
#endif
}
-void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
+static void bvhtree_node_inflate(const BVHTree *tree, BVHNode *node, const float dist)
{
axis_t axis_iter;
+ for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
+ float dist_corrected = dist * bvhtree_kdop_axes_length[axis_iter];
+ node->bv[(2 * axis_iter)] -= dist_corrected; /* minimum */
+ node->bv[(2 * axis_iter) + 1] += dist_corrected; /* maximum */
+ }
+}
+
+void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
+{
BVHNode *node = NULL;
/* insert should only possible as long as tree->totbranch is 0 */
@@ -986,10 +1012,7 @@ void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoin
node->index = index;
/* inflate the bv with some epsilon */
- for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
- node->bv[(2 * axis_iter)] -= tree->epsilon; /* minimum */
- node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */
- }
+ bvhtree_node_inflate(tree, node, tree->epsilon);
}
/* call before BLI_bvhtree_update_tree() */
@@ -997,7 +1020,6 @@ bool BLI_bvhtree_update_node(
BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints)
{
BVHNode *node = NULL;
- axis_t axis_iter;
/* check if index exists */
if (index > tree->totleaf) {
@@ -1013,10 +1035,7 @@ bool BLI_bvhtree_update_node(
}
/* inflate the bv with some epsilon */
- for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
- node->bv[(2 * axis_iter)] -= tree->epsilon; /* minimum */
- node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */
- }
+ bvhtree_node_inflate(tree, node, tree->epsilon);
return true;
}
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 34886054cb0..301d9dc2296 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -15,7 +15,8 @@
*
* The Original Code is written by Rob Haarsma (phase)
* All rights reserved.
- * This code parses the Freetype font outline data to chains of Blender's beziertriples.
+ *
+ * This code parses the Freetype font outline data to chains of Blender's bezier-triples.
* Additional information can be found at the bottom of this file.
*
* Code that uses exotic character maps is present but commented out.
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 97c77ed2e19..580c833d8dc 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -186,6 +186,9 @@ void BLO_update_defaults_workspace(struct WorkSpace *workspace, const char *app_
/* Version patch user preferences. */
void BLO_version_defaults_userpref_blend(struct Main *mainvar, struct UserDef *userdef);
+/* Disable unwanted experimental feature settings on startup. */
+void BLO_sanitize_experimental_features_userpref_blend(struct UserDef *userdef);
+
struct BlendThumbnail *BLO_thumbnail_from_file(const char *filepath);
/* datafiles (generated theme) */
diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt
index c56e0b5ad2e..f5c7223a37c 100644
--- a/source/blender/blenloader/CMakeLists.txt
+++ b/source/blender/blenloader/CMakeLists.txt
@@ -101,8 +101,8 @@ add_dependencies(bf_blenloader bf_dna)
if(WITH_GTESTS)
set(TEST_SRC
- tests/blendfile_loading_base_test.cc
tests/blendfile_load_test.cc
+ tests/blendfile_loading_base_test.cc
)
set(TEST_INC
)
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 12b5a297df5..bc13e3b3a39 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -190,17 +190,19 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
/* Patch first frame for old files. */
Scene *scene = bmain->scenes.first;
- LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
- if (ob->type != OB_GPENCIL) {
- continue;
- }
- bGPdata *gpd = ob->data;
- LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- bGPDframe *gpf = gpl->frames.first;
- if (gpf && gpf->framenum > scene->r.sfra) {
- bGPDframe *gpf_dup = BKE_gpencil_frame_duplicate(gpf);
- gpf_dup->framenum = scene->r.sfra;
- BLI_addhead(&gpl->frames, gpf_dup);
+ if (scene != NULL) {
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ if (ob->type != OB_GPENCIL) {
+ continue;
+ }
+ bGPdata *gpd = ob->data;
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ bGPDframe *gpf = gpl->frames.first;
+ if (gpf && gpf->framenum > scene->r.sfra) {
+ bGPDframe *gpf_dup = BKE_gpencil_frame_duplicate(gpf);
+ gpf_dup->framenum = scene->r.sfra;
+ BLI_addhead(&gpl->frames, gpf_dup);
+ }
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index e2dc27d7e88..0b116804481 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -38,6 +38,7 @@
#include "DNA_windowmanager_types.h"
#include "BKE_addon.h"
+#include "BKE_blender_version.h"
#include "BKE_colorband.h"
#include "BKE_idprop.h"
#include "BKE_keyconfig.h"
@@ -784,4 +785,23 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef)
#undef USER_VERSION_ATLEAST
}
+void BLO_sanitize_experimental_features_userpref_blend(UserDef *userdef)
+{
+ /* User preference experimental settings are only supported in alpha builds.
+ * This prevents users corrupting data and relying on API that may change.
+ *
+ * If user preferences are saved this will be stored in disk as expected.
+ * This only starts to take effect when there is a release branch (on beta).
+ *
+ * At that time master already has its version bumped so its user preferences
+ * are not touched by these settings. */
+
+ if (BKE_blender_version_is_alpha()) {
+ return;
+ }
+ userdef->experimental.use_new_particle_system = false;
+ userdef->experimental.use_new_hair_type = false;
+ userdef->experimental.use_sculpt_vertex_colors = false;
+}
+
#undef USER_LMOUSESELECT
diff --git a/source/blender/blenloader/tests/blendfile_loading_base_test.cc b/source/blender/blenloader/tests/blendfile_loading_base_test.cc
index d74bab4b31c..c743e6bcd3f 100644
--- a/source/blender/blenloader/tests/blendfile_loading_base_test.cc
+++ b/source/blender/blenloader/tests/blendfile_loading_base_test.cc
@@ -148,7 +148,7 @@ void BlendfileLoadingBaseTest::depsgraph_create(eEvaluationMode depsgraph_evalua
{
depsgraph = DEG_graph_new(
bfile->main, bfile->curscene, bfile->cur_view_layer, depsgraph_evaluation_mode);
- DEG_graph_build_from_view_layer(depsgraph, bfile->main, bfile->curscene, bfile->cur_view_layer);
+ DEG_graph_build_from_view_layer(depsgraph);
BKE_scene_graph_update_tagged(depsgraph, bfile->main);
}
diff --git a/source/blender/blenloader/tests/blendfile_loading_base_test.h b/source/blender/blenloader/tests/blendfile_loading_base_test.h
index a5e75ef6df8..f90e07218fb 100644
--- a/source/blender/blenloader/tests/blendfile_loading_base_test.h
+++ b/source/blender/blenloader/tests/blendfile_loading_base_test.h
@@ -56,9 +56,9 @@ class BlendfileLoadingBaseTest : public testing::Test {
void blendfile_free();
/* Create a depsgraph. Assumes a blend file has been loaded to this->bfile. */
- void depsgraph_create(eEvaluationMode depsgraph_evaluation_mode);
+ virtual void depsgraph_create(eEvaluationMode depsgraph_evaluation_mode);
/* Free the depsgraph if it's not nullptr. */
- void depsgraph_free();
+ virtual void depsgraph_free();
};
#endif /* __BLENDFILE_LOADING_BASE_TEST_H__ */
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index 0eeb0d21b5b..7368e3d044d 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -154,10 +154,10 @@ set(SRC
tools/bmesh_path.h
tools/bmesh_path_region.c
tools/bmesh_path_region.h
- tools/bmesh_path_uv.c
- tools/bmesh_path_uv.h
tools/bmesh_path_region_uv.c
tools/bmesh_path_region_uv.h
+ tools/bmesh_path_uv.c
+ tools/bmesh_path_uv.h
tools/bmesh_region_match.c
tools/bmesh_region_match.h
tools/bmesh_separate.c
diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h
index b200fa8d266..79c1ebcfe9f 100644
--- a/source/blender/compositor/COM_compositor.h
+++ b/source/blender/compositor/COM_compositor.h
@@ -362,4 +362,3 @@ void COM_deinitialize(void);
#ifdef __cplusplus
}
#endif
-
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index 417aaa2c4c0..e0916491edb 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -55,6 +55,7 @@ set(SRC
intern/builder/deg_builder_rna.cc
intern/builder/deg_builder_transitive.cc
intern/builder/pipeline.cc
+ intern/builder/pipeline_all_objects.cc
intern/builder/pipeline_compositor.cc
intern/builder/pipeline_from_ids.cc
intern/builder/pipeline_render.cc
@@ -106,16 +107,17 @@ set(SRC
intern/builder/deg_builder.h
intern/builder/deg_builder_cache.h
intern/builder/deg_builder_cycle.h
- intern/builder/deg_builder_relations_drivers.h
intern/builder/deg_builder_map.h
intern/builder/deg_builder_nodes.h
intern/builder/deg_builder_pchanmap.h
intern/builder/deg_builder_relations.h
+ intern/builder/deg_builder_relations_drivers.h
intern/builder/deg_builder_relations_impl.h
intern/builder/deg_builder_remove_noop.h
intern/builder/deg_builder_rna.h
intern/builder/deg_builder_transitive.h
intern/builder/pipeline.h
+ intern/builder/pipeline_all_objects.h
intern/builder/pipeline_compositor.h
intern/builder/pipeline_from_ids.h
intern/builder/pipeline_render.h
diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h
index b3636743101..8f33e9f480d 100644
--- a/source/blender/depsgraph/DEG_depsgraph.h
+++ b/source/blender/depsgraph/DEG_depsgraph.h
@@ -149,16 +149,11 @@ void DEG_ids_check_recalc(struct Main *bmain,
/* Graph Evaluation ----------------------------- */
-/* Frame changed recalculation entry point
- * < context_type: context to perform evaluation for
- * < ctime: (frame) new frame to evaluate values on
- */
-void DEG_evaluate_on_framechange(struct Main *bmain, Depsgraph *graph, float ctime);
+/* Frame changed recalculation entry point. */
+void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime);
-/* Data changed recalculation entry point.
- * < context_type: context to perform evaluation for
- */
-void DEG_evaluate_on_refresh(struct Main *bmain, Depsgraph *graph);
+/* Data changed recalculation entry point. */
+void DEG_evaluate_on_refresh(Depsgraph *graph);
bool DEG_needs_eval(Depsgraph *graph);
diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h
index 50f22b00028..2147a584765 100644
--- a/source/blender/depsgraph/DEG_depsgraph_build.h
+++ b/source/blender/depsgraph/DEG_depsgraph_build.h
@@ -51,44 +51,29 @@ extern "C" {
/* Graph Building -------------------------------- */
/* Build depsgraph for the given scene, and dump results in given graph container. */
-void DEG_graph_build_from_view_layer(struct Depsgraph *graph,
- struct Main *bmain,
- struct Scene *scene,
- struct ViewLayer *view_layer);
+void DEG_graph_build_from_view_layer(struct Depsgraph *graph);
+
+/* Build depsgraph for all objects (so also invisible ones) in the given view layer. */
+void DEG_graph_build_for_all_objects(struct Depsgraph *graph);
/* Special version of builder which produces dependency graph suitable for the render pipeline.
* It will contain sequencer and compositor (if needed) and all their dependencies. */
-void DEG_graph_build_for_render_pipeline(struct Depsgraph *graph,
- struct Main *bmain,
- struct Scene *scene,
- struct ViewLayer *view_layer);
+void DEG_graph_build_for_render_pipeline(struct Depsgraph *graph);
/* Builds minimal dependency graph for compositor preview.
*
* Note that compositor editor might have pinned node tree, which is different from scene's node
* tree.
*/
-void DEG_graph_build_for_compositor_preview(struct Depsgraph *graph,
- struct Main *bmain,
- struct Scene *scene,
- struct ViewLayer *view_layer,
- struct bNodeTree *nodetree);
-
-void DEG_graph_build_from_ids(struct Depsgraph *graph,
- struct Main *bmain,
- struct Scene *scene,
- struct ViewLayer *view_layer,
- struct ID **ids,
- const int num_ids);
+void DEG_graph_build_for_compositor_preview(struct Depsgraph *graph, struct bNodeTree *nodetree);
+
+void DEG_graph_build_from_ids(struct Depsgraph *graph, struct ID **ids, const int num_ids);
/* Tag relations from the given graph for update. */
void DEG_graph_tag_relations_update(struct Depsgraph *graph);
/* Create or update relations in the specified graph. */
-void DEG_graph_relations_update(struct Depsgraph *graph,
- struct Main *bmain,
- struct Scene *scene,
- struct ViewLayer *view_layer);
+void DEG_graph_relations_update(struct Depsgraph *graph);
/* Tag all relations in the database for update.*/
void DEG_relations_tag_update(struct Main *bmain);
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index e0166a13d69..7eb5f1ccec1 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -55,6 +55,9 @@ struct Scene *DEG_get_input_scene(const Depsgraph *graph);
/* Get view layer that depsgraph was built for. */
struct ViewLayer *DEG_get_input_view_layer(const Depsgraph *graph);
+/* Get bmain that depsgraph was built for. */
+struct Main *DEG_get_bmain(const Depsgraph *graph);
+
/* Get evaluation mode that depsgraph was built for. */
eEvaluationMode DEG_get_mode(const Depsgraph *graph);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 37b23833e00..c0b692f28c1 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -978,13 +978,13 @@ void DepsgraphRelationBuilder::build_object_parent(Object *object)
break;
}
}
- /* Metaballs are the odd balls here (no pun intended): they will request
+ /* Meta-balls are the odd balls here (no pun intended): they will request
* instance-list (formerly known as dupli-list) during evaluation. This is
* their way of interacting with all instanced surfaces, making a nice
* effect when is used form particle system. */
if (object->type == OB_MBALL && parent->transflag & OB_DUPLI) {
ComponentKey parent_geometry_key(parent_id, NodeType::GEOMETRY);
- /* NOTE: Metaballs are evaluating geometry only after their transform,
+ /* NOTE: Meta-balls are evaluating geometry only after their transform,
* so we only hook up to transform channel here. */
add_relation(parent_geometry_key, object_transform_key, "Parent");
}
diff --git a/source/blender/depsgraph/intern/builder/pipeline.cc b/source/blender/depsgraph/intern/builder/pipeline.cc
index d6893ba11d8..b13077e4792 100644
--- a/source/blender/depsgraph/intern/builder/pipeline.cc
+++ b/source/blender/depsgraph/intern/builder/pipeline.cc
@@ -33,14 +33,11 @@
namespace blender {
namespace deg {
-AbstractBuilderPipeline::AbstractBuilderPipeline(::Depsgraph *graph,
- Main *bmain,
- Scene *scene,
- ViewLayer *view_layer)
+AbstractBuilderPipeline::AbstractBuilderPipeline(::Depsgraph *graph)
: deg_graph_(reinterpret_cast<Depsgraph *>(graph)),
- bmain_(bmain),
- scene_(scene),
- view_layer_(view_layer),
+ bmain_(deg_graph_->bmain),
+ scene_(deg_graph_->scene),
+ view_layer_(deg_graph_->view_layer),
builder_cache_()
{
}
diff --git a/source/blender/depsgraph/intern/builder/pipeline.h b/source/blender/depsgraph/intern/builder/pipeline.h
index 2c9c78bb2cb..d98d834932c 100644
--- a/source/blender/depsgraph/intern/builder/pipeline.h
+++ b/source/blender/depsgraph/intern/builder/pipeline.h
@@ -49,7 +49,7 @@ class DepsgraphRelationBuilder;
*/
class AbstractBuilderPipeline {
public:
- AbstractBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer);
+ AbstractBuilderPipeline(::Depsgraph *graph);
virtual ~AbstractBuilderPipeline();
void build();
diff --git a/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc b/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc
new file mode 100644
index 00000000000..81d239239be
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_all_objects.cc
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline_all_objects.h"
+
+#include "intern/builder/deg_builder_nodes.h"
+#include "intern/builder/deg_builder_relations.h"
+#include "intern/depsgraph.h"
+
+#include "DNA_layer_types.h"
+
+namespace blender {
+namespace deg {
+
+namespace {
+
+class AllObjectsNodeBuilder : public DepsgraphNodeBuilder {
+ public:
+ AllObjectsNodeBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache)
+ : DepsgraphNodeBuilder(bmain, graph, cache)
+ {
+ }
+
+ virtual bool need_pull_base_into_graph(Base * /*base*/) override
+ {
+ return true;
+ }
+};
+
+class AllObjectsRelationBuilder : public DepsgraphRelationBuilder {
+ public:
+ AllObjectsRelationBuilder(Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache)
+ : DepsgraphRelationBuilder(bmain, graph, cache)
+ {
+ }
+
+ virtual bool need_pull_base_into_graph(Base * /*base*/) override
+ {
+ return true;
+ }
+};
+
+} // namespace
+
+AllObjectsBuilderPipeline::AllObjectsBuilderPipeline(::Depsgraph *graph)
+ : ViewLayerBuilderPipeline(graph)
+{
+}
+
+unique_ptr<DepsgraphNodeBuilder> AllObjectsBuilderPipeline::construct_node_builder()
+{
+ return std::make_unique<AllObjectsNodeBuilder>(bmain_, deg_graph_, &builder_cache_);
+}
+
+unique_ptr<DepsgraphRelationBuilder> AllObjectsBuilderPipeline::construct_relation_builder()
+{
+ return std::make_unique<AllObjectsRelationBuilder>(bmain_, deg_graph_, &builder_cache_);
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_all_objects.h b/source/blender/depsgraph/intern/builder/pipeline_all_objects.h
new file mode 100644
index 00000000000..11ca2314331
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_all_objects.h
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "pipeline_view_layer.h"
+
+namespace blender {
+namespace deg {
+
+/* Builds a dependency graph that contains all objects in the view layer.
+ * This is contrary to the regular ViewLayerBuilderPipeline, which is limited to visible objects
+ * (and their dependencies). */
+class AllObjectsBuilderPipeline : public ViewLayerBuilderPipeline {
+ public:
+ AllObjectsBuilderPipeline(::Depsgraph *graph);
+
+ protected:
+ virtual unique_ptr<DepsgraphNodeBuilder> construct_node_builder() override;
+ virtual unique_ptr<DepsgraphRelationBuilder> construct_relation_builder() override;
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_compositor.cc b/source/blender/depsgraph/intern/builder/pipeline_compositor.cc
index 3e56f17fc7e..2b9922851c1 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_compositor.cc
+++ b/source/blender/depsgraph/intern/builder/pipeline_compositor.cc
@@ -26,9 +26,8 @@
namespace blender {
namespace deg {
-CompositorBuilderPipeline::CompositorBuilderPipeline(
- ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, bNodeTree *nodetree)
- : AbstractBuilderPipeline(graph, bmain, scene, view_layer), nodetree_(nodetree)
+CompositorBuilderPipeline::CompositorBuilderPipeline(::Depsgraph *graph, bNodeTree *nodetree)
+ : AbstractBuilderPipeline(graph), nodetree_(nodetree)
{
deg_graph_->is_render_pipeline_depsgraph = true;
}
diff --git a/source/blender/depsgraph/intern/builder/pipeline_compositor.h b/source/blender/depsgraph/intern/builder/pipeline_compositor.h
index 892ece7c2a4..46f1e3694d3 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_compositor.h
+++ b/source/blender/depsgraph/intern/builder/pipeline_compositor.h
@@ -32,8 +32,7 @@ namespace deg {
class CompositorBuilderPipeline : public AbstractBuilderPipeline {
public:
- CompositorBuilderPipeline(
- ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, bNodeTree *nodetree);
+ CompositorBuilderPipeline(::Depsgraph *graph, bNodeTree *nodetree);
protected:
virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override;
diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
index e44f554f197..87cfeb46693 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
+++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
@@ -32,11 +32,9 @@ namespace {
class DepsgraphFromIDsFilter {
public:
- DepsgraphFromIDsFilter(ID **ids, const int num_ids)
+ DepsgraphFromIDsFilter(Span<ID *> ids)
{
- for (int i = 0; i < num_ids; ++i) {
- ids_.add(ids[i]);
- }
+ ids_.add_multiple(ids);
}
bool contains(ID *id)
@@ -50,9 +48,11 @@ class DepsgraphFromIDsFilter {
class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
public:
- DepsgraphFromIDsNodeBuilder(
- Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
- : DepsgraphNodeBuilder(bmain, graph, cache), filter_(ids, num_ids)
+ DepsgraphFromIDsNodeBuilder(Main *bmain,
+ Depsgraph *graph,
+ DepsgraphBuilderCache *cache,
+ Span<ID *> ids)
+ : DepsgraphNodeBuilder(bmain, graph, cache), filter_(ids)
{
}
@@ -81,9 +81,11 @@ class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
public:
- DepsgraphFromIDsRelationBuilder(
- Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
- : DepsgraphRelationBuilder(bmain, graph, cache), filter_(ids, num_ids)
+ DepsgraphFromIDsRelationBuilder(Main *bmain,
+ Depsgraph *graph,
+ DepsgraphBuilderCache *cache,
+ Span<ID *> ids)
+ : DepsgraphRelationBuilder(bmain, graph, cache), filter_(ids)
{
}
@@ -112,41 +114,35 @@ class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
} // namespace
-FromIDsBuilderPipeline::FromIDsBuilderPipeline(::Depsgraph *graph,
- Main *bmain,
- Scene *scene,
- ViewLayer *view_layer,
- ID **ids,
- const int num_ids)
- : AbstractBuilderPipeline(graph, bmain, scene, view_layer), ids_(ids), num_ids_(num_ids)
+FromIDsBuilderPipeline::FromIDsBuilderPipeline(::Depsgraph *graph, Span<ID *> ids)
+ : AbstractBuilderPipeline(graph), ids_(ids)
{
}
unique_ptr<DepsgraphNodeBuilder> FromIDsBuilderPipeline::construct_node_builder()
{
- return std::make_unique<DepsgraphFromIDsNodeBuilder>(
- bmain_, deg_graph_, &builder_cache_, ids_, num_ids_);
+ return std::make_unique<DepsgraphFromIDsNodeBuilder>(bmain_, deg_graph_, &builder_cache_, ids_);
}
unique_ptr<DepsgraphRelationBuilder> FromIDsBuilderPipeline::construct_relation_builder()
{
return std::make_unique<DepsgraphFromIDsRelationBuilder>(
- bmain_, deg_graph_, &builder_cache_, ids_, num_ids_);
+ bmain_, deg_graph_, &builder_cache_, ids_);
}
void FromIDsBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder)
{
node_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY);
- for (int i = 0; i < num_ids_; ++i) {
- node_builder.build_id(ids_[i]);
+ for (ID *id : ids_) {
+ node_builder.build_id(id);
}
}
void FromIDsBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder)
{
relation_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY);
- for (int i = 0; i < num_ids_; ++i) {
- relation_builder.build_id(ids_[i]);
+ for (ID *id : ids_) {
+ relation_builder.build_id(id);
}
}
diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.h b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h
index 4a507f2c728..79fcfc52446 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_from_ids.h
+++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h
@@ -43,8 +43,7 @@ namespace deg {
class FromIDsBuilderPipeline : public AbstractBuilderPipeline {
public:
- FromIDsBuilderPipeline(
- ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, ID **ids, int num_ids);
+ FromIDsBuilderPipeline(::Depsgraph *graph, Span<ID *> ids);
protected:
virtual unique_ptr<DepsgraphNodeBuilder> construct_node_builder() override;
@@ -54,8 +53,7 @@ class FromIDsBuilderPipeline : public AbstractBuilderPipeline {
virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override;
private:
- ID **ids_;
- const int num_ids_;
+ Span<ID *> ids_;
};
} // namespace deg
diff --git a/source/blender/depsgraph/intern/builder/pipeline_render.cc b/source/blender/depsgraph/intern/builder/pipeline_render.cc
index 50a37d0d3e4..3b065f7f1bc 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_render.cc
+++ b/source/blender/depsgraph/intern/builder/pipeline_render.cc
@@ -26,11 +26,7 @@
namespace blender {
namespace deg {
-RenderBuilderPipeline::RenderBuilderPipeline(::Depsgraph *graph,
- Main *bmain,
- Scene *scene,
- ViewLayer *view_layer)
- : AbstractBuilderPipeline(graph, bmain, scene, view_layer)
+RenderBuilderPipeline::RenderBuilderPipeline(::Depsgraph *graph) : AbstractBuilderPipeline(graph)
{
deg_graph_->is_render_pipeline_depsgraph = true;
}
diff --git a/source/blender/depsgraph/intern/builder/pipeline_render.h b/source/blender/depsgraph/intern/builder/pipeline_render.h
index df7f9e0de68..91a4be137b6 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_render.h
+++ b/source/blender/depsgraph/intern/builder/pipeline_render.h
@@ -30,7 +30,7 @@ namespace deg {
class RenderBuilderPipeline : public AbstractBuilderPipeline {
public:
- RenderBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer);
+ RenderBuilderPipeline(::Depsgraph *graph);
protected:
virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override;
diff --git a/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc b/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc
index 3223f17f349..f1852a40a10 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc
@@ -26,11 +26,8 @@
namespace blender {
namespace deg {
-ViewLayerBuilderPipeline::ViewLayerBuilderPipeline(::Depsgraph *graph,
- Main *bmain,
- Scene *scene,
- ViewLayer *view_layer)
- : AbstractBuilderPipeline(graph, bmain, scene, view_layer)
+ViewLayerBuilderPipeline::ViewLayerBuilderPipeline(::Depsgraph *graph)
+ : AbstractBuilderPipeline(graph)
{
}
diff --git a/source/blender/depsgraph/intern/builder/pipeline_view_layer.h b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h
index fbd7b98acad..aa85dd7a47b 100644
--- a/source/blender/depsgraph/intern/builder/pipeline_view_layer.h
+++ b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h
@@ -30,7 +30,7 @@ namespace deg {
class ViewLayerBuilderPipeline : public AbstractBuilderPipeline {
public:
- ViewLayerBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer);
+ ViewLayerBuilderPipeline(::Depsgraph *graph);
protected:
virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override;
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index fb933cb38f3..96c17ae4dc5 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -44,6 +44,7 @@
#include "DEG_depsgraph_debug.h"
#include "builder/deg_builder_relations.h"
+#include "builder/pipeline_all_objects.h"
#include "builder/pipeline_compositor.h"
#include "builder/pipeline_from_ids.h"
#include "builder/pipeline_render.h"
@@ -209,39 +210,33 @@ struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *node_handle)
/* Graph Building API's */
/* Build depsgraph for the given scene layer, and dump results in given graph container. */
-void DEG_graph_build_from_view_layer(Depsgraph *graph,
- Main *bmain,
- Scene *scene,
- ViewLayer *view_layer)
+void DEG_graph_build_from_view_layer(Depsgraph *graph)
{
- deg::ViewLayerBuilderPipeline builder(graph, bmain, scene, view_layer);
+ deg::ViewLayerBuilderPipeline builder(graph);
builder.build();
}
-void DEG_graph_build_for_render_pipeline(Depsgraph *graph,
- Main *bmain,
- Scene *scene,
- ViewLayer *view_layer)
+void DEG_graph_build_for_all_objects(struct Depsgraph *graph)
{
- deg::RenderBuilderPipeline builder(graph, bmain, scene, view_layer);
+ deg::AllObjectsBuilderPipeline builder(graph);
builder.build();
}
-void DEG_graph_build_for_compositor_preview(
- Depsgraph *graph, Main *bmain, Scene *scene, struct ViewLayer *view_layer, bNodeTree *nodetree)
+void DEG_graph_build_for_render_pipeline(Depsgraph *graph)
{
- deg::CompositorBuilderPipeline builder(graph, bmain, scene, view_layer, nodetree);
+ deg::RenderBuilderPipeline builder(graph);
builder.build();
}
-void DEG_graph_build_from_ids(Depsgraph *graph,
- Main *bmain,
- Scene *scene,
- ViewLayer *view_layer,
- ID **ids,
- const int num_ids)
+void DEG_graph_build_for_compositor_preview(Depsgraph *graph, bNodeTree *nodetree)
{
- deg::FromIDsBuilderPipeline builder(graph, bmain, scene, view_layer, ids, num_ids);
+ deg::CompositorBuilderPipeline builder(graph, nodetree);
+ builder.build();
+}
+
+void DEG_graph_build_from_ids(Depsgraph *graph, ID **ids, const int num_ids)
+{
+ deg::FromIDsBuilderPipeline builder(graph, blender::Span(ids, num_ids));
builder.build();
}
@@ -264,14 +259,14 @@ void DEG_graph_tag_relations_update(Depsgraph *graph)
}
/* Create or update relations in the specified graph. */
-void DEG_graph_relations_update(Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer)
+void DEG_graph_relations_update(Depsgraph *graph)
{
deg::Depsgraph *deg_graph = (deg::Depsgraph *)graph;
if (!deg_graph->need_update) {
/* Graph is up to date, nothing to do. */
return;
}
- DEG_graph_build_from_view_layer(graph, bmain, scene, view_layer);
+ DEG_graph_build_from_view_layer(graph);
}
/* Tag all relations for update. */
diff --git a/source/blender/depsgraph/intern/depsgraph_debug.cc b/source/blender/depsgraph/intern/depsgraph_debug.cc
index 0763738ff59..c5e306f3148 100644
--- a/source/blender/depsgraph/intern/depsgraph_debug.cc
+++ b/source/blender/depsgraph/intern/depsgraph_debug.cc
@@ -93,7 +93,7 @@ bool DEG_debug_graph_relations_validate(Depsgraph *graph,
{
Depsgraph *temp_depsgraph = DEG_graph_new(bmain, scene, view_layer, DEG_get_mode(graph));
bool valid = true;
- DEG_graph_build_from_view_layer(temp_depsgraph, bmain, scene, view_layer);
+ DEG_graph_build_from_view_layer(temp_depsgraph);
if (!DEG_debug_compare(temp_depsgraph, graph)) {
fprintf(stderr, "ERROR! Depsgraph wasn't tagged for update when it should have!\n");
BLI_assert(!"This should not happen!");
diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc
index 8a641f23a42..0c116f5863c 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.cc
+++ b/source/blender/depsgraph/intern/depsgraph_eval.cc
@@ -48,32 +48,26 @@
namespace deg = blender::deg;
/* Evaluate all nodes tagged for updating. */
-void DEG_evaluate_on_refresh(Main *bmain, Depsgraph *graph)
+void DEG_evaluate_on_refresh(Depsgraph *graph)
{
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
deg_graph->ctime = BKE_scene_frame_get(deg_graph->scene);
- /* Update time on primary timesource. */
- deg::TimeSourceNode *tsrc = deg_graph->find_time_source();
- tsrc->cfra = deg_graph->ctime;
/* Update time in scene. */
if (deg_graph->scene_cow) {
BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime);
}
- deg::deg_graph_flush_updates(bmain, deg_graph);
+ deg::deg_graph_flush_updates(deg_graph);
deg::deg_evaluate_on_refresh(deg_graph);
deg_graph->need_update_time = false;
}
/* Frame-change happened for root scene that graph belongs to. */
-void DEG_evaluate_on_framechange(Main *bmain, Depsgraph *graph, float ctime)
+void DEG_evaluate_on_framechange(Depsgraph *graph, float ctime)
{
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
deg_graph->ctime = ctime;
- /* Update time on primary timesource. */
- deg::TimeSourceNode *tsrc = deg_graph->find_time_source();
- tsrc->cfra = ctime;
deg_graph->need_update_time = true;
- deg::deg_graph_flush_updates(bmain, deg_graph);
+ deg::deg_graph_flush_updates(deg_graph);
/* Update time in scene. */
if (deg_graph->scene_cow) {
BKE_scene_frame_set(deg_graph->scene_cow, deg_graph->ctime);
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index 0b6014c18f1..fc9ed9a6ab9 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -61,6 +61,12 @@ struct ViewLayer *DEG_get_input_view_layer(const Depsgraph *graph)
return deg_graph->view_layer;
}
+struct Main *DEG_get_bmain(const Depsgraph *graph)
+{
+ const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
+ return deg_graph->bmain;
+}
+
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
{
const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index 048c0125f53..7d47e1fb541 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -106,8 +106,8 @@ bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, DupliObject
* visible otherwise. The better solution eventually would be for objects
* to specify which object they instance, instead of through parenting.
*
- * This function should not be used for metaballs. They have custom visibility rules, as hiding
- * the base metaball will also hide all the other balls in the group. */
+ * This function should not be used for meta-balls. They have custom visibility rules, as hiding
+ * the base meta-ball will also hide all the other balls in the group. */
if (eval_mode == DAG_EVAL_RENDER || dob) {
const int hide_original_types = OB_DUPLIVERTS | OB_DUPLIFACES;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index 1ede2cf914a..2e0487bfca1 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -86,8 +86,8 @@ enum class EvaluationStage {
/* Workaround for areas which can not be evaluated in threads.
*
- * For example, metaballs, which are iterating over all bases and are requesting dupli-lists
- * to see whether there are metaballs inside. */
+ * For example, meta-balls, which are iterating over all bases and are requesting dupli-lists
+ * to see whether there are meta-balls inside. */
SINGLE_THREADED_WORKAROUND,
};
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index a74ec485d88..dea23c9f96d 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -351,11 +351,12 @@ void invalidate_tagged_evaluated_data(Depsgraph *graph)
/* Flush updates from tagged nodes outwards until all affected nodes
* are tagged.
*/
-void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
+void deg_graph_flush_updates(Depsgraph *graph)
{
/* Sanity checks. */
- BLI_assert(bmain != nullptr);
BLI_assert(graph != nullptr);
+ Main *bmain = graph->bmain;
+
/* Nothing to update, early out. */
if (graph->need_update_time) {
const Scene *scene_orig = graph->scene;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.h b/source/blender/depsgraph/intern/eval/deg_eval_flush.h
index c76dc9fe01d..1f58c54dbf4 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.h
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.h
@@ -35,7 +35,7 @@ struct Depsgraph;
/* Flush updates from tagged nodes outwards until all affected nodes
* are tagged.
*/
-void deg_graph_flush_updates(struct Main *bmain, struct Depsgraph *graph);
+void deg_graph_flush_updates(struct Depsgraph *graph);
/* Clear tags from all operation nodes. */
void deg_graph_clear_tags(struct Depsgraph *graph);
diff --git a/source/blender/depsgraph/intern/node/deg_node_time.h b/source/blender/depsgraph/intern/node/deg_node_time.h
index 364c214b014..fe17684abb0 100644
--- a/source/blender/depsgraph/intern/node/deg_node_time.h
+++ b/source/blender/depsgraph/intern/node/deg_node_time.h
@@ -30,12 +30,6 @@ namespace deg {
/* Time Source Node. */
struct TimeSourceNode : public Node {
- /* New "current time". */
- float cfra;
-
- /* time-offset relative to the "official" time source that this one has. */
- float offset;
-
// TODO: evaluate() operation needed
virtual void tag_update(Depsgraph *graph, eUpdateSource source) override;
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 6d2577d5b78..a785d27c2db 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -1302,8 +1302,8 @@ void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float
EEVEE_LightBake *lbake = (EEVEE_LightBake *)custom_data;
Depsgraph *depsgraph = lbake->depsgraph;
- DEG_graph_relations_update(depsgraph, lbake->bmain, lbake->scene, lbake->view_layer_input);
- DEG_evaluate_on_framechange(lbake->bmain, depsgraph, lbake->frame);
+ DEG_graph_relations_update(depsgraph);
+ DEG_evaluate_on_framechange(depsgraph, lbake->frame);
lbake->view_layer = DEG_get_evaluated_view_layer(depsgraph);
lbake->stop = stop;
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index 9aae801197f..052fb485b19 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -78,7 +78,8 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
e_data.dummy_horizon_tx = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, pixel);
}
- if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) {
+ if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED ||
+ stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) {
const float *viewport_size = DRW_viewport_size_get();
const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
@@ -101,10 +102,11 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->ao_bounce_fac = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BOUNCE) ? 1.0f : 0.0f;
- effects->gtao_horizons = DRW_texture_pool_query_2d(
+ effects->gtao_horizons_renderpass = DRW_texture_pool_query_2d(
fs_size[0], fs_size[1], GPU_RGBA8, &draw_engine_eevee_type);
GPU_framebuffer_ensure_config(
- &fbl->gtao_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->gtao_horizons)});
+ &fbl->gtao_fb,
+ {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->gtao_horizons_renderpass)});
if (G.debug_value == 6) {
effects->gtao_horizons_debug = DRW_texture_pool_query_2d(
@@ -117,10 +119,15 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
effects->gtao_horizons_debug = NULL;
}
+ effects->gtao_horizons = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) ?
+ effects->gtao_horizons_renderpass :
+ e_data.dummy_horizon_tx;
+
return EFFECT_GTAO | EFFECT_NORMAL_BUFFER;
}
/* Cleanup */
+ effects->gtao_horizons_renderpass = e_data.dummy_horizon_tx;
effects->gtao_horizons = e_data.dummy_horizon_tx;
GPU_FRAMEBUFFER_FREE_SAFE(fbl->gtao_fb);
common_data->ao_settings = 0.0f;
@@ -136,45 +143,41 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
EEVEE_PassList *psl = vedata->psl;
EEVEE_EffectsInfo *effects = stl->effects;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
-
- if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) {
- const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F;
+ const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F;
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-
- /* Should be enough precision for many samples. */
- DRW_texture_ensure_fullscreen_2d(&txl->ao_accum, texture_format, 0);
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- GPU_framebuffer_ensure_config(&fbl->ao_accum_fb,
- {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ao_accum)});
+ /* Should be enough precision for many samples. */
+ DRW_texture_ensure_fullscreen_2d(&txl->ao_accum, texture_format, 0);
- /* Clear texture. */
- if (effects->taa_current_sample == 1) {
- GPU_framebuffer_bind(fbl->ao_accum_fb);
- GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear);
- }
+ GPU_framebuffer_ensure_config(&fbl->ao_accum_fb,
+ {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ao_accum)});
- /* Accumulation pass */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD;
- DRW_PASS_CREATE(psl->ao_accum_ps, state);
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_accum_ps);
- DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
- DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
- DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
- DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
- DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ /* Clear texture. */
+ if (effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->ao_accum_fb);
+ GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear);
}
- else {
- /* Cleanup to release memory */
- DRW_TEXTURE_FREE_SAFE(txl->ao_accum);
- GPU_FRAMEBUFFER_FREE_SAFE(fbl->ao_accum_fb);
+
+ /* Clear texture. */
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->ao_accum_fb);
+ GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear);
}
+
+ /* Accumulation pass */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD;
+ DRW_PASS_CREATE(psl->ao_accum_ps, state);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_accum_ps);
+ DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
+ DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
+ DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
+ DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons_renderpass);
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
@@ -225,7 +228,7 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
- DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
+ DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons_renderpass);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
DRW_shgroup_call(grp, quad, NULL);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 1e2de521cdf..40d7676c38c 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -679,8 +679,9 @@ typedef struct EEVEE_EffectsInfo {
struct DRWView *taa_view;
/* Ambient Occlusion */
int ao_depth_layer;
- struct GPUTexture *ao_src_depth; /* pointer copy */
- struct GPUTexture *gtao_horizons; /* Textures from pool */
+ struct GPUTexture *ao_src_depth; /* pointer copy */
+ struct GPUTexture *gtao_horizons; /* Textures from pool */
+ struct GPUTexture *gtao_horizons_renderpass; /* Texture when rendering render pass */
struct GPUTexture *gtao_horizons_debug;
/* Motion Blur */
float current_ndc_to_world[4][4];
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 21a4013e309..65a856c39e1 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -359,11 +359,6 @@ static void eevee_render_result_occlusion(RenderLayer *rl,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
- if ((vedata->stl->effects->enabled_effects & EFFECT_GTAO) == 0) {
- /* AO is not enabled. */
- return;
- }
-
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) {
EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AO);
eevee_render_color_result(
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index 089d8b7a287..55fe5882211 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -90,12 +90,8 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata)
if (v3d) {
const Scene *scene = draw_ctx->scene;
eViewLayerEEVEEPassType render_pass = v3d->shading.render_pass;
- if (render_pass == EEVEE_RENDER_PASS_AO &&
- ((scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0)) {
- render_pass = EEVEE_RENDER_PASS_COMBINED;
- }
- else if (render_pass == EEVEE_RENDER_PASS_BLOOM &&
- ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) {
+ if (render_pass == EEVEE_RENDER_PASS_BLOOM &&
+ ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) {
render_pass = EEVEE_RENDER_PASS_COMBINED;
}
g_data->render_passes = render_pass;
@@ -392,8 +388,6 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
((stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) != 0) ?
(stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) :
stl->g_data->render_passes;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
bool is_valid = (render_pass & EEVEE_RENDERPASSES_ALL) > 0;
bool needs_color_transfer = (render_pass & EEVEE_RENDERPASSES_COLOR_PASS) > 0 &&
@@ -405,12 +399,6 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
is_valid = false;
}
- /* When SSS isn't available, but the pass is requested, we mark it as invalid */
- if ((render_pass & EEVEE_RENDER_PASS_AO) != 0 &&
- (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0) {
- is_valid = false;
- }
-
const int current_sample = stl->effects->taa_current_sample;
const int total_samples = stl->effects->taa_total_sample;
if ((render_pass & EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE) &&
@@ -462,10 +450,10 @@ void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata)
tx = txl->color_double_buffer;
break;
case 6:
- tx = effects->gtao_horizons;
+ tx = effects->gtao_horizons_renderpass;
break;
case 7:
- tx = effects->gtao_horizons;
+ tx = effects->gtao_horizons_renderpass;
break;
case 8:
tx = effects->sss_irradiance;
diff --git a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl b/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl
index a400aadb052..9311542a79e 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_curve_handle_geom.glsl
@@ -58,7 +58,7 @@ void main()
if ((curveHandleDisplay != CURVE_HANDLE_ALL) && (!handle_selected)) {
/* Nurbs must show the handles always. */
bool is_u_segment = (((vertFlag[1] ^ vertFlag[0]) & EVEN_U_BIT) != 0);
- if (!is_u_segment) {
+ if ((!is_u_segment) && (color_id <= 4)) {
return;
}
}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl
index 5818d8eca52..a6161d36a07 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_gpencil_vert.glsl
@@ -73,7 +73,7 @@ void main()
}
#ifdef USE_POINTS
- gl_PointSize = sizeVertex * 2.0;
+ gl_PointSize = sizeVertexGpencil * 2.0;
if (is_point_dimmed) {
finalColor.rgb = clamp(colorUnselect.rgb + vec3(0.3), 0.0, 1.0);
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
index 71816f6ff6e..899ada852f9 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
@@ -1,4 +1,4 @@
-
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
/**
diff --git a/source/blender/draw/engines/workbench/workbench_shader.c b/source/blender/draw/engines/workbench/workbench_shader.c
index 9cc5087bd36..af3b5d31b2b 100644
--- a/source/blender/draw/engines/workbench/workbench_shader.c
+++ b/source/blender/draw/engines/workbench/workbench_shader.c
@@ -380,24 +380,26 @@ void workbench_shader_depth_of_field_get(GPUShader **prepare_sh,
GPUShader **resolve_sh)
{
if (e_data.dof_prepare_sh == NULL) {
- char *frag = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_workbench_effect_dof_frag_glsl);
- e_data.dof_prepare_sh = DRW_shader_create_fullscreen(frag, "#define PREPARE\n");
- e_data.dof_downsample_sh = DRW_shader_create_fullscreen(frag, "#define DOWNSAMPLE\n");
+ e_data.dof_prepare_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define PREPARE\n");
+ e_data.dof_downsample_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define DOWNSAMPLE\n");
#if 0 /* TODO(fclem) finish COC min_max optimization */
- e_data.dof_flatten_v_sh = DRW_shader_create_fullscreen(frag,
- "#define FLATTEN_VERTICAL\n");
- e_data.dof_flatten_h_sh = DRW_shader_create_fullscreen(frag,
- "#define FLATTEN_HORIZONTAL\n");
- e_data.dof_dilate_v_sh = DRW_shader_create_fullscreen(frag,
- "#define DILATE_VERTICAL\n");
- e_data.dof_dilate_h_sh = DRW_shader_create_fullscreen(frag,
- "#define DILATE_HORIZONTAL\n");
+ e_data.dof_flatten_v_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define FLATTEN_VERTICAL\n");
+ e_data.dof_flatten_h_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define FLATTEN_HORIZONTAL\n");
+ e_data.dof_dilate_v_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define DILATE_VERTICAL\n");
+ e_data.dof_dilate_h_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define DILATE_HORIZONTAL\n");
#endif
- e_data.dof_blur1_sh = DRW_shader_create_fullscreen(frag, "#define BLUR1\n");
- e_data.dof_blur2_sh = DRW_shader_create_fullscreen(frag, "#define BLUR2\n");
- e_data.dof_resolve_sh = DRW_shader_create_fullscreen(frag, "#define RESOLVE\n");
- MEM_freeN(frag);
+ e_data.dof_blur1_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define BLUR1\n");
+ e_data.dof_blur2_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define BLUR2\n");
+ e_data.dof_resolve_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_workbench_effect_dof_frag_glsl, e_data.lib, "#define RESOLVE\n");
}
*prepare_sh = e_data.dof_prepare_sh;
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 956bddfb357..63625fae185 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -208,27 +208,44 @@ typedef void (*GPUMaterialEvalCallbackFn)(struct GPUMaterial *mat,
const char **defines);
#endif
-struct GPUShader *DRW_shader_create(const char *vert,
- const char *geom,
- const char *frag,
- const char *defines);
-struct GPUShader *DRW_shader_create_with_lib(
- const char *vert, const char *geom, const char *frag, const char *lib, const char *defines);
-struct GPUShader *DRW_shader_create_with_shaderlib(const char *vert,
- const char *geom,
- const char *frag,
- const DRWShaderLibrary *lib,
- const char *defines);
+struct GPUShader *DRW_shader_create_ex(
+ const char *vert, const char *geom, const char *frag, const char *defines, const char *func);
+struct GPUShader *DRW_shader_create_with_lib_ex(const char *vert,
+ const char *geom,
+ const char *frag,
+ const char *lib,
+ const char *defines,
+ const char *func);
+struct GPUShader *DRW_shader_create_with_shaderlib_ex(const char *vert,
+ const char *geom,
+ const char *frag,
+ const DRWShaderLibrary *lib,
+ const char *defines,
+ const char *func);
struct GPUShader *DRW_shader_create_with_transform_feedback(const char *vert,
const char *geom,
const char *defines,
const eGPUShaderTFBType prim_type,
const char **varying_names,
const int varying_count);
-struct GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines);
-struct GPUShader *DRW_shader_create_fullscreen_with_shaderlib(const char *frag,
- const DRWShaderLibrary *lib,
- const char *defines);
+struct GPUShader *DRW_shader_create_fullscreen_ex(const char *frag,
+ const char *defines,
+ const char *func);
+struct GPUShader *DRW_shader_create_fullscreen_with_shaderlib_ex(const char *frag,
+ const DRWShaderLibrary *lib,
+ const char *defines,
+ const char *func);
+#define DRW_shader_create(vert, geom, frag, defines) \
+ DRW_shader_create_ex(vert, geom, frag, defines, __func__)
+#define DRW_shader_create_with_lib(vert, geom, frag, lib, defines) \
+ DRW_shader_create_with_lib_ex(vert, geom, frag, lib, defines, __func__)
+#define DRW_shader_create_with_shaderlib(vert, geom, frag, lib, defines) \
+ DRW_shader_create_with_shaderlib_ex(vert, geom, frag, lib, defines, __func__)
+#define DRW_shader_create_fullscreen(frag, defines) \
+ DRW_shader_create_fullscreen_ex(frag, defines, __func__)
+#define DRW_shader_create_fullscreen_with_shaderlib(frag, lib, defines) \
+ DRW_shader_create_fullscreen_with_shaderlib_ex(frag, lib, defines, __func__)
+
struct GPUMaterial *DRW_shader_find_from_world(struct World *wo,
const void *engine_type,
const int options,
@@ -344,6 +361,10 @@ typedef enum {
#define DRW_STATE_DEFAULT \
(DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL)
+#define DRW_STATE_BLEND_ENABLED \
+ (DRW_STATE_BLEND_ADD | DRW_STATE_BLEND_ADD_FULL | DRW_STATE_BLEND_ALPHA | \
+ DRW_STATE_BLEND_ALPHA_PREMUL | DRW_STATE_BLEND_BACKGROUND | DRW_STATE_BLEND_OIT | \
+ DRW_STATE_BLEND_MUL | DRW_STATE_BLEND_SUB | DRW_STATE_BLEND_CUSTOM | DRW_STATE_LOGIC_INVERT)
#define DRW_STATE_RASTERIZER_ENABLED \
(DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_STENCIL | \
DRW_STATE_WRITE_STENCIL_SHADOW_PASS | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL)
@@ -718,7 +739,6 @@ bool DRW_state_draw_background(void);
/* Avoid too many lookups while drawing */
typedef struct DRWContextState {
-
struct ARegion *region; /* 'CTX_wm_region(C)' */
struct RegionView3D *rv3d; /* 'CTX_wm_region_view3d(C)' */
struct View3D *v3d; /* 'CTX_wm_view3d(C)' */
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index f0d73d5bb84..aac9af088de 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -187,6 +187,7 @@ void DRW_globals_update(void)
/* M_SQRT2 to be at least the same size of the old square */
gb->sizeVertex = U.pixelsize *
(max_ff(1.0f, UI_GetThemeValuef(TH_VERTEX_SIZE) * (float)M_SQRT2 / 2.0f));
+ gb->sizeVertexGpencil = U.pixelsize * UI_GetThemeValuef(TH_GP_VERTEX_SIZE);
gb->sizeFaceDot = U.pixelsize * UI_GetThemeValuef(TH_FACEDOT_SIZE);
gb->sizeEdge = U.pixelsize * (1.0f / 2.0f); /* TODO Theme */
gb->sizeEdgeFix = U.pixelsize * (0.5f + 2.0f * (2.0f * (gb->sizeEdge * (float)M_SQRT1_2)));
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index 6060dce47ac..d6402127e5e 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -150,8 +150,7 @@ typedef struct GlobalsUboStorage {
float sizeObjectCenter, sizeLightCenter, sizeLightCircle, sizeLightCircleShadow;
float sizeVertex, sizeEdge, sizeEdgeFix, sizeFaceDot;
float sizeChecker;
-
- float pad_globalsBlock;
+ float sizeVertexGpencil;
} GlobalsUboStorage;
/* Keep in sync with globalsBlock in shaders */
BLI_STATIC_ASSERT_ALIGN(GlobalsUboStorage, 16)
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index e436424b460..d90d7d36ebc 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -1595,8 +1595,7 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
GPU_clear_color(0.0f, 0.0f, 0.0f, 1.0f);
GPU_clear(GPU_COLOR_BIT);
/* Premult Alpha over black background. */
- GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA_PREMULT);
}
GPU_matrix_identity_set();
@@ -1606,9 +1605,7 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
if (draw_background) {
/* Reset default. */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* Free temporary viewport. */
@@ -1758,8 +1755,6 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
BLI_rcti_init(&render_rect, 0, size[0], 0, size[1]);
}
- /* Set the default Blender draw state */
- GPU_state_init();
/* Reset state before drawing */
DRW_state_reset();
@@ -2475,7 +2470,7 @@ void DRW_draw_depth_object(
GPU_SHADER_CFG_DEFAULT;
GPU_batch_program_set_builtin_with_config(batch, GPU_SHADER_3D_DEPTH_ONLY, sh_cfg);
if (world_clip_planes != NULL) {
- GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes[0]);
+ GPU_batch_uniform_4fv_array(batch, "WorldClipPlanes", 6, world_clip_planes);
}
GPU_batch_draw(batch);
@@ -2788,8 +2783,6 @@ void DRW_opengl_context_create(void)
if (!G.background) {
immActivate();
}
- /* Set default Blender OpenGL state */
- GPU_state_init();
/* So we activate the window's one afterwards. */
wm_window_reset_drawable();
}
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index b931bdd0cbe..44e2eec04d9 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -31,8 +31,8 @@
#include "GPU_extensions.h"
#include "GPU_platform.h"
-#include "intern/gpu_primitive_private.h"
-#include "intern/gpu_shader_private.h"
+#include "GPU_shader.h"
+#include "GPU_state.h"
#ifdef USE_GPU_SELECT
# include "GPU_select.h"
@@ -82,309 +82,169 @@ void drw_state_set(DRWState state)
return;
}
-#define CHANGED_TO(f) \
- ((DST.state_lock & (f)) ? \
- 0 : \
- (((DST.state & (f)) ? ((state & (f)) ? 0 : -1) : ((state & (f)) ? 1 : 0))))
+ eGPUWriteMask write_mask = 0;
+ eGPUBlend blend = 0;
+ eGPUFaceCullTest culling_test = 0;
+ eGPUDepthTest depth_test = 0;
+ eGPUStencilTest stencil_test = 0;
+ eGPUStencilOp stencil_op = 0;
+ eGPUProvokingVertex provoking_vert = 0;
-#define CHANGED_ANY(f) (((DST.state & (f)) != (state & (f))) && ((DST.state_lock & (f)) == 0))
-
-#define CHANGED_ANY_STORE_VAR(f, enabled) \
- (((DST.state & (f)) != (enabled = (state & (f)))) && (((DST.state_lock & (f)) == 0)))
-
- /* Depth Write */
- {
- int test;
- if ((test = CHANGED_TO(DRW_STATE_WRITE_DEPTH))) {
- GPU_depth_mask(test == 1);
- }
+ if (state & DRW_STATE_WRITE_DEPTH) {
+ write_mask |= GPU_WRITE_DEPTH;
}
-
- /* Stencil Write */
- {
- DRWState test;
- if (CHANGED_ANY_STORE_VAR(DRW_STATE_WRITE_STENCIL_ENABLED, test)) {
- /* Stencil Write */
- if (test) {
- glStencilMask(0xFF);
- switch (test) {
- case DRW_STATE_WRITE_STENCIL:
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
- break;
- case DRW_STATE_WRITE_STENCIL_SHADOW_PASS:
- glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
- glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
- break;
- case DRW_STATE_WRITE_STENCIL_SHADOW_FAIL:
- glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP);
- glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP);
- break;
- default:
- BLI_assert(0);
- }
- }
- else {
- glStencilMask(0x00);
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- }
- }
+ if (state & DRW_STATE_WRITE_COLOR) {
+ write_mask |= GPU_WRITE_COLOR;
}
- /* Color Write */
- {
- int test;
- if ((test = CHANGED_TO(DRW_STATE_WRITE_COLOR))) {
- if (test == 1) {
- GPU_color_mask(true, true, true, true);
- }
- else {
- GPU_color_mask(false, false, false, false);
- }
- }
+ switch (state & (DRW_STATE_CULL_BACK | DRW_STATE_CULL_FRONT)) {
+ case DRW_STATE_CULL_BACK:
+ culling_test = GPU_CULL_BACK;
+ break;
+ case DRW_STATE_CULL_FRONT:
+ culling_test = GPU_CULL_FRONT;
+ break;
+ default:
+ culling_test = GPU_CULL_NONE;
+ break;
}
- /* Raster Discard */
- {
- if (CHANGED_ANY(DRW_STATE_RASTERIZER_ENABLED)) {
- if ((state & DRW_STATE_RASTERIZER_ENABLED) != 0) {
- glDisable(GL_RASTERIZER_DISCARD);
- }
- else {
- glEnable(GL_RASTERIZER_DISCARD);
- }
- }
+ switch (state & DRW_STATE_DEPTH_TEST_ENABLED) {
+ case DRW_STATE_DEPTH_LESS:
+ depth_test = GPU_DEPTH_LESS;
+ break;
+ case DRW_STATE_DEPTH_LESS_EQUAL:
+ depth_test = GPU_DEPTH_LESS_EQUAL;
+ break;
+ case DRW_STATE_DEPTH_EQUAL:
+ depth_test = GPU_DEPTH_EQUAL;
+ break;
+ case DRW_STATE_DEPTH_GREATER:
+ depth_test = GPU_DEPTH_GREATER;
+ break;
+ case DRW_STATE_DEPTH_GREATER_EQUAL:
+ depth_test = GPU_DEPTH_GREATER_EQUAL;
+ break;
+ case DRW_STATE_DEPTH_ALWAYS:
+ depth_test = GPU_DEPTH_ALWAYS;
+ break;
+ default:
+ depth_test = GPU_DEPTH_NONE;
+ break;
}
- /* Cull */
- {
- DRWState test;
- if (CHANGED_ANY_STORE_VAR(DRW_STATE_CULL_BACK | DRW_STATE_CULL_FRONT, test)) {
- if (test) {
- glEnable(GL_CULL_FACE);
-
- if ((state & DRW_STATE_CULL_BACK) != 0) {
- glCullFace(GL_BACK);
- }
- else if ((state & DRW_STATE_CULL_FRONT) != 0) {
- glCullFace(GL_FRONT);
- }
- else {
- BLI_assert(0);
- }
- }
- else {
- glDisable(GL_CULL_FACE);
- }
- }
+ switch (state & DRW_STATE_WRITE_STENCIL_ENABLED) {
+ case DRW_STATE_WRITE_STENCIL:
+ stencil_op = GPU_STENCIL_OP_REPLACE;
+ GPU_stencil_write_mask_set(0xFF);
+ break;
+ case DRW_STATE_WRITE_STENCIL_SHADOW_PASS:
+ stencil_op = GPU_STENCIL_OP_COUNT_DEPTH_PASS;
+ GPU_stencil_write_mask_set(0xFF);
+ break;
+ case DRW_STATE_WRITE_STENCIL_SHADOW_FAIL:
+ stencil_op = GPU_STENCIL_OP_COUNT_DEPTH_FAIL;
+ GPU_stencil_write_mask_set(0xFF);
+ break;
+ default:
+ stencil_op = GPU_STENCIL_OP_NONE;
+ GPU_stencil_write_mask_set(0x00);
+ break;
}
- /* Depth Test */
- {
- DRWState test;
- if (CHANGED_ANY_STORE_VAR(DRW_STATE_DEPTH_TEST_ENABLED, test)) {
- if (test) {
- glEnable(GL_DEPTH_TEST);
-
- switch (test) {
- case DRW_STATE_DEPTH_LESS:
- glDepthFunc(GL_LESS);
- break;
- case DRW_STATE_DEPTH_LESS_EQUAL:
- glDepthFunc(GL_LEQUAL);
- break;
- case DRW_STATE_DEPTH_EQUAL:
- glDepthFunc(GL_EQUAL);
- break;
- case DRW_STATE_DEPTH_GREATER:
- glDepthFunc(GL_GREATER);
- break;
- case DRW_STATE_DEPTH_GREATER_EQUAL:
- glDepthFunc(GL_GEQUAL);
- break;
- case DRW_STATE_DEPTH_ALWAYS:
- glDepthFunc(GL_ALWAYS);
- break;
- default:
- BLI_assert(0);
- }
- }
- else {
- glDisable(GL_DEPTH_TEST);
- }
- }
+ switch (state & DRW_STATE_STENCIL_TEST_ENABLED) {
+ case DRW_STATE_STENCIL_ALWAYS:
+ stencil_test = GPU_STENCIL_ALWAYS;
+ break;
+ case DRW_STATE_STENCIL_EQUAL:
+ stencil_test = GPU_STENCIL_EQUAL;
+ break;
+ case DRW_STATE_STENCIL_NEQUAL:
+ stencil_test = GPU_STENCIL_NEQUAL;
+ break;
+ default:
+ stencil_test = GPU_STENCIL_NONE;
+ break;
}
- /* Stencil Test */
- {
- int test;
- if (CHANGED_ANY_STORE_VAR(DRW_STATE_STENCIL_TEST_ENABLED, test)) {
- if (test) {
- glEnable(GL_STENCIL_TEST);
- }
- else {
- glDisable(GL_STENCIL_TEST);
- }
- }
+ switch (state & DRW_STATE_BLEND_ENABLED) {
+ case DRW_STATE_BLEND_ADD:
+ blend = GPU_BLEND_ADDITIVE;
+ break;
+ case DRW_STATE_BLEND_ADD_FULL:
+ blend = GPU_BLEND_ADDITIVE_PREMULT;
+ break;
+ case DRW_STATE_BLEND_ALPHA:
+ blend = GPU_BLEND_ALPHA;
+ break;
+ case DRW_STATE_BLEND_ALPHA_PREMUL:
+ blend = GPU_BLEND_ALPHA_PREMULT;
+ break;
+ case DRW_STATE_BLEND_BACKGROUND:
+ blend = GPU_BLEND_BACKGROUND;
+ break;
+ case DRW_STATE_BLEND_OIT:
+ blend = GPU_BLEND_OIT;
+ break;
+ case DRW_STATE_BLEND_MUL:
+ blend = GPU_BLEND_MULTIPLY;
+ break;
+ case DRW_STATE_BLEND_SUB:
+ blend = GPU_BLEND_SUBTRACT;
+ break;
+ case DRW_STATE_BLEND_CUSTOM:
+ blend = GPU_BLEND_CUSTOM;
+ break;
+ case DRW_STATE_LOGIC_INVERT:
+ blend = GPU_BLEND_INVERT;
+ break;
+ default:
+ blend = GPU_BLEND_NONE;
+ break;
}
- /* Blending (all buffer) */
- {
- int test;
- if (CHANGED_ANY_STORE_VAR(DRW_STATE_BLEND_ALPHA | DRW_STATE_BLEND_ALPHA_PREMUL |
- DRW_STATE_BLEND_ADD | DRW_STATE_BLEND_MUL |
- DRW_STATE_BLEND_ADD_FULL | DRW_STATE_BLEND_OIT |
- DRW_STATE_BLEND_BACKGROUND | DRW_STATE_BLEND_CUSTOM |
- DRW_STATE_LOGIC_INVERT | DRW_STATE_BLEND_SUB,
- test)) {
- if (test) {
- glEnable(GL_BLEND);
-
- switch (test) {
- case DRW_STATE_BLEND_ALPHA:
- glBlendFuncSeparate(GL_SRC_ALPHA,
- GL_ONE_MINUS_SRC_ALPHA, /* RGB */
- GL_ONE,
- GL_ONE_MINUS_SRC_ALPHA); /* Alpha */
- break;
- case DRW_STATE_BLEND_BACKGROUND:
- /* Special blend to add color under and multiply dst by alpha. */
- glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA,
- GL_SRC_ALPHA, /* RGB */
- GL_ZERO,
- GL_SRC_ALPHA); /* Alpha */
- break;
- case DRW_STATE_BLEND_ALPHA_PREMUL:
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- break;
- case DRW_STATE_BLEND_MUL:
- glBlendFunc(GL_DST_COLOR, GL_ZERO);
- break;
- case DRW_STATE_BLEND_OIT:
- glBlendFuncSeparate(GL_ONE,
- GL_ONE, /* RGB */
- GL_ZERO,
- GL_ONE_MINUS_SRC_ALPHA); /* Alpha */
- break;
- case DRW_STATE_BLEND_ADD:
- /* Do not let alpha accumulate but premult the source RGB by it. */
- glBlendFuncSeparate(GL_SRC_ALPHA,
- GL_ONE, /* RGB */
- GL_ZERO,
- GL_ONE); /* Alpha */
- break;
- case DRW_STATE_BLEND_ADD_FULL:
- /* Let alpha accumulate. */
- glBlendFunc(GL_ONE, GL_ONE);
- break;
- case DRW_STATE_BLEND_SUB:
- glBlendFunc(GL_ONE, GL_ONE);
- break;
- case DRW_STATE_BLEND_CUSTOM:
- /* Custom blend parameters using dual source blending.
- * Can only be used with one Draw Buffer. */
- glBlendFunc(GL_ONE, GL_SRC1_COLOR);
- break;
- case DRW_STATE_LOGIC_INVERT:
- /* Replace logic op by blend func to support floating point framebuffer. */
- glBlendFuncSeparate(GL_ONE_MINUS_DST_COLOR,
- GL_ZERO, /* RGB */
- GL_ZERO,
- GL_ONE); /* Alpha */
- break;
- default:
- BLI_assert(0);
- }
+ GPU_state_set(
+ write_mask, blend, culling_test, depth_test, stencil_test, stencil_op, provoking_vert);
- if (test == DRW_STATE_BLEND_SUB) {
- glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
- }
- else {
- glBlendEquation(GL_FUNC_ADD);
- }
- }
- else {
- glDisable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE); /* Don't multiply incoming color by alpha. */
- }
- }
+ if (state & DRW_STATE_SHADOW_OFFSET) {
+ GPU_shadow_offset(true);
}
-
- /* Shadow Bias */
- {
- int test;
- if ((test = CHANGED_TO(DRW_STATE_SHADOW_OFFSET))) {
- if (test == 1) {
- glEnable(GL_POLYGON_OFFSET_FILL);
- glEnable(GL_POLYGON_OFFSET_LINE);
- /* 2.0 Seems to be the lowest possible slope bias that works in every case. */
- glPolygonOffset(2.0f, 1.0f);
- }
- else {
- glDisable(GL_POLYGON_OFFSET_FILL);
- glDisable(GL_POLYGON_OFFSET_LINE);
- }
- }
+ else {
+ GPU_shadow_offset(false);
}
- /* In Front objects selection */
- {
- int test;
- if ((test = CHANGED_TO(DRW_STATE_IN_FRONT_SELECT))) {
- if (test == 1) {
- /* XXX `GPU_depth_range` is not a perfect solution
- * since very distant geometries can still be occluded.
- * Also the depth test precision of these geometries is impaired.
- * However, it solves the selection for the vast majority of cases. */
- GPU_depth_range(0.0f, 0.01f);
- }
- else {
- GPU_depth_range(0.0f, 1.0f);
- }
- }
+ /* TODO this should be part of shader state. */
+ if (state & DRW_STATE_CLIP_PLANES) {
+ GPU_clip_distances(DST.view_active->clip_planes_len);
}
-
- /* Clip Planes */
- {
- int test;
- if ((test = CHANGED_TO(DRW_STATE_CLIP_PLANES))) {
- if (test == 1) {
- GPU_clip_distances(DST.view_active->clip_planes_len);
- }
- else {
- GPU_clip_distances(0);
- }
- }
+ else {
+ GPU_clip_distances(0);
}
- /* Program Points Size */
- {
- int test;
- if ((test = CHANGED_TO(DRW_STATE_PROGRAM_POINT_SIZE))) {
- if (test == 1) {
- GPU_program_point_size(true);
- }
- else {
- GPU_program_point_size(false);
- }
- }
+ if (state & DRW_STATE_IN_FRONT_SELECT) {
+ /* XXX `GPU_depth_range` is not a perfect solution
+ * since very distant geometries can still be occluded.
+ * Also the depth test precision of these geometries is impaired.
+ * However, it solves the selection for the vast majority of cases. */
+ GPU_depth_range(0.0f, 0.01f);
+ }
+ else {
+ GPU_depth_range(0.0f, 1.0f);
}
- /* Provoking Vertex */
- {
- int test;
- if ((test = CHANGED_TO(DRW_STATE_FIRST_VERTEX_CONVENTION))) {
- if (test == 1) {
- glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
- }
- else {
- glProvokingVertex(GL_LAST_VERTEX_CONVENTION);
- }
- }
+ if (state & DRW_STATE_PROGRAM_POINT_SIZE) {
+ GPU_program_point_size(true);
+ }
+ else {
+ GPU_program_point_size(false);
}
-#undef CHANGED_TO
-#undef CHANGED_ANY
-#undef CHANGED_ANY_STORE_VAR
+ if (state & DRW_STATE_FIRST_VERTEX_CONVENTION) {
+ GPU_provoking_vertex(GPU_VERTEX_FIRST);
+ }
+ else {
+ GPU_provoking_vertex(GPU_VERTEX_LAST);
+ }
DST.state = state;
}
@@ -396,17 +256,9 @@ static void drw_stencil_state_set(uint write_mask, uint reference, uint compare_
* stencil_value being the value stored in the stencil buffer.
* - (write-mask & reference) is what gets written if the test condition is fulfilled.
**/
- glStencilMask(write_mask);
- DRWState stencil_test = DST.state & DRW_STATE_STENCIL_TEST_ENABLED;
- if (stencil_test == DRW_STATE_STENCIL_ALWAYS) {
- glStencilFunc(GL_ALWAYS, reference, compare_mask);
- }
- else if (stencil_test == DRW_STATE_STENCIL_EQUAL) {
- glStencilFunc(GL_EQUAL, reference, compare_mask);
- }
- else if (stencil_test == DRW_STATE_STENCIL_NEQUAL) {
- glStencilFunc(GL_NOTEQUAL, reference, compare_mask);
- }
+ GPU_stencil_write_mask_set(write_mask);
+ GPU_stencil_reference_set(reference);
+ GPU_stencil_compare_mask_set(compare_mask);
}
/* Reset state to not interfer with other UI drawcall */
@@ -821,8 +673,8 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
break;
case DRW_UNIFORM_TFEEDBACK_TARGET:
BLI_assert(uni->pvalue && (*use_tfeedback == false));
- *use_tfeedback = GPU_shader_transform_feedback_enable(
- shgroup->shader, ((GPUVertBuf *)uni->pvalue)->vbo_id);
+ *use_tfeedback = GPU_shader_transform_feedback_enable(shgroup->shader,
+ ((GPUVertBuf *)uni->pvalue));
break;
/* Legacy/Fallback support. */
case DRW_UNIFORM_BASE_INSTANCE:
@@ -922,7 +774,7 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa
int chunk = DRW_handle_chunk_get(handle);
if (state->resource_chunk != chunk) {
if (state->chunkid_loc != -1) {
- GPU_shader_uniform_int(NULL, state->chunkid_loc, chunk);
+ GPU_shader_uniform_int(DST.shader, state->chunkid_loc, chunk);
}
if (state->obmats_loc != -1) {
GPU_uniformbuffer_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]);
@@ -938,7 +790,7 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa
if (state->resourceid_loc != -1) {
int id = DRW_handle_id_get(handle);
if (state->resource_id != id) {
- GPU_shader_uniform_int(NULL, state->resourceid_loc, id);
+ GPU_shader_uniform_int(DST.shader, state->resourceid_loc, id);
state->resource_id = id;
}
}
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index 1c260721efb..7602bbb39ac 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -312,16 +312,18 @@ void DRW_deferred_shader_remove(GPUMaterial *mat)
/** \{ */
-GPUShader *DRW_shader_create(const char *vert,
- const char *geom,
- const char *frag,
- const char *defines)
+GPUShader *DRW_shader_create_ex(
+ const char *vert, const char *geom, const char *frag, const char *defines, const char *name)
{
- return GPU_shader_create(vert, frag, geom, NULL, defines, __func__);
+ return GPU_shader_create(vert, frag, geom, NULL, defines, name);
}
-GPUShader *DRW_shader_create_with_lib(
- const char *vert, const char *geom, const char *frag, const char *lib, const char *defines)
+GPUShader *DRW_shader_create_with_lib_ex(const char *vert,
+ const char *geom,
+ const char *frag,
+ const char *lib,
+ const char *defines,
+ const char *name)
{
GPUShader *sh;
char *vert_with_lib = NULL;
@@ -334,7 +336,7 @@ GPUShader *DRW_shader_create_with_lib(
geom_with_lib = BLI_string_joinN(lib, geom);
}
- sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, __func__);
+ sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, name);
MEM_freeN(vert_with_lib);
MEM_freeN(frag_with_lib);
@@ -345,18 +347,19 @@ GPUShader *DRW_shader_create_with_lib(
return sh;
}
-GPUShader *DRW_shader_create_with_shaderlib(const char *vert,
- const char *geom,
- const char *frag,
- const DRWShaderLibrary *lib,
- const char *defines)
+GPUShader *DRW_shader_create_with_shaderlib_ex(const char *vert,
+ const char *geom,
+ const char *frag,
+ const DRWShaderLibrary *lib,
+ const char *defines,
+ const char *name)
{
GPUShader *sh;
char *vert_with_lib = DRW_shader_library_create_shader_string(lib, vert);
char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag);
char *geom_with_lib = (geom) ? DRW_shader_library_create_shader_string(lib, geom) : NULL;
- sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, __func__);
+ sh = GPU_shader_create(vert_with_lib, frag_with_lib, geom_with_lib, NULL, defines, name);
MEM_SAFE_FREE(vert_with_lib);
MEM_SAFE_FREE(frag_with_lib);
@@ -383,22 +386,22 @@ GPUShader *DRW_shader_create_with_transform_feedback(const char *vert,
__func__);
}
-GPUShader *DRW_shader_create_fullscreen(const char *frag, const char *defines)
+GPUShader *DRW_shader_create_fullscreen_ex(const char *frag, const char *defines, const char *name)
{
- return GPU_shader_create(
- datatoc_common_fullscreen_vert_glsl, frag, NULL, NULL, defines, __func__);
+ return GPU_shader_create(datatoc_common_fullscreen_vert_glsl, frag, NULL, NULL, defines, name);
}
-GPUShader *DRW_shader_create_fullscreen_with_shaderlib(const char *frag,
- const DRWShaderLibrary *lib,
- const char *defines)
+GPUShader *DRW_shader_create_fullscreen_with_shaderlib_ex(const char *frag,
+ const DRWShaderLibrary *lib,
+ const char *defines,
+ const char *name)
{
GPUShader *sh;
char *vert = datatoc_common_fullscreen_vert_glsl;
char *frag_with_lib = DRW_shader_library_create_shader_string(lib, frag);
- sh = GPU_shader_create(vert, frag_with_lib, NULL, NULL, defines, __func__);
+ sh = GPU_shader_create(vert, frag_with_lib, NULL, NULL, defines, name);
MEM_SAFE_FREE(frag_with_lib);
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index 1458ff5341c..0dc35d44788 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -123,7 +123,7 @@ void DRW_draw_cursor(void)
/* Draw nice Anti Aliased cursor. */
GPU_line_width(1.0f);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
float eps = 1e-5f;
@@ -188,7 +188,7 @@ void DRW_draw_cursor(void)
GPU_batch_draw(cursor_batch);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
GPU_matrix_pop();
GPU_matrix_projection_set(original_proj);
diff --git a/source/blender/draw/intern/shaders/common_globals_lib.glsl b/source/blender/draw/intern/shaders/common_globals_lib.glsl
index 40a527a6ba4..bd1b1fb6f3a 100644
--- a/source/blender/draw/intern/shaders/common_globals_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_globals_lib.glsl
@@ -117,8 +117,7 @@ layout(std140) uniform globalsBlock
float sizeEdgeFix;
float sizeFaceDot;
float sizeChecker;
-
- float pad_globalsBlock;
+ float sizeVertexGpencil;
};
#define sizeViewportInv (sizeViewport.zw)
diff --git a/source/blender/draw/intern/smaa_textures.h b/source/blender/draw/intern/smaa_textures.h
index 7556f3a1952..fcf0ced1eed 100644
--- a/source/blender/draw/intern/smaa_textures.h
+++ b/source/blender/draw/intern/smaa_textures.h
@@ -15081,4 +15081,3 @@ static const unsigned char searchTexBytes[] = {
};
/* clang-format off */
-
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 53401e0c05a..0a464e6709a 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -4386,9 +4386,7 @@ void ANIM_channel_draw(
}
/* set blending again, as may not be set in previous step */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* step 1) draw backdrop ........................................... */
if (acf->draw_backdrop) {
@@ -4437,7 +4435,7 @@ void ANIM_channel_draw(
}
/* turn off blending, since not needed anymore... */
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* icon is drawn as widget now... */
if (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index b2f687b49af..73df0518f06 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -98,9 +98,7 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
/* only draw this if preview range is set */
if (PRVRANGEON) {
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -121,7 +119,7 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
@@ -133,9 +131,7 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
void ANIM_draw_framerange(Scene *scene, View2D *v2d)
{
/* draw darkened area outside of active timeline frame range */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -151,7 +147,7 @@ void ANIM_draw_framerange(Scene *scene, View2D *v2d)
immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* thin lines where the actual frames are */
immUniformThemeColorShade(TH_BACK, -60);
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index bcdbf4c74f0..3bfa3b9d5be 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -499,16 +499,14 @@ static void draw_marker(
marker_color_get(marker, text_color, line_color);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
draw_marker_line(line_color, xpos, UI_DPI_FAC * 20, region_height);
int icon_id = marker_get_icon_id(marker, flag);
UI_icon_draw(xpos - 0.55f * UI_DPI_ICON_SIZE, UI_DPI_FAC * 18, icon_id);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
float name_y = UI_DPI_FAC * 18;
/* Give an offset to the marker name when selected,
@@ -529,13 +527,11 @@ static void draw_markers_background(rctf *rect)
immUniformColor4ubv(shade);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();
}
diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c
index 4c10c66dfa6..2a37302872a 100644
--- a/source/blender/editors/animation/anim_motion_paths.c
+++ b/source/blender/editors/animation/anim_motion_paths.c
@@ -69,9 +69,9 @@ typedef struct MPathTarget {
/* ........ */
/* update scene for current frame */
-static void motionpaths_calc_update_scene(Main *bmain, struct Depsgraph *depsgraph)
+static void motionpaths_calc_update_scene(struct Depsgraph *depsgraph)
{
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
Depsgraph *animviz_depsgraph_build(Main *bmain,
@@ -91,11 +91,11 @@ Depsgraph *animviz_depsgraph_build(Main *bmain,
}
/* Build graph from all requested IDs. */
- DEG_graph_build_from_ids(depsgraph, bmain, scene, view_layer, ids, num_ids);
+ DEG_graph_build_from_ids(depsgraph, ids, num_ids);
MEM_freeN(ids);
/* Update once so we can access pointers of evaluated animation data. */
- motionpaths_calc_update_scene(bmain, depsgraph);
+ motionpaths_calc_update_scene(depsgraph);
return depsgraph;
}
@@ -471,7 +471,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph,
}
else {
/* Update relevant data for new frame. */
- motionpaths_calc_update_scene(bmain, depsgraph);
+ motionpaths_calc_update_scene(depsgraph);
}
/* perform baking for targets */
@@ -484,7 +484,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph,
* We always have to restore the current frame though. */
CFRA = cfra;
if (range != ANIMVIZ_CALC_RANGE_CURRENT_FRAME && restore) {
- motionpaths_calc_update_scene(bmain, depsgraph);
+ motionpaths_calc_update_scene(depsgraph);
}
if (is_active_depsgraph) {
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index c69f3ce3e3a..4d6d7fa3ad5 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -692,7 +692,7 @@ static void draw_keylist(View2D *v2d,
const float smaller_sz = 0.35f * icon_sz;
const float ipo_sz = 0.1f * icon_sz;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
/* TODO: allow this opacity factor to be themed? */
@@ -848,7 +848,7 @@ static void draw_keylist(View2D *v2d,
}
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* *************************** Channel Drawing Funcs *************************** */
diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c
index edc36326c57..0615e21c4a5 100644
--- a/source/blender/editors/animation/time_scrub_ui.c
+++ b/source/blender/editors/animation/time_scrub_ui.c
@@ -66,13 +66,11 @@ static void draw_background(const rcti *rect)
immUniformThemeColor(TH_TIME_SCRUB_BACKGROUND);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();
}
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 748bf040fbb..2dac273501d 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -420,7 +420,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C),
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
GPU_depth_test(false);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
GPU_line_width(3.0f);
@@ -442,7 +442,7 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C),
/* Reset defaults */
GPU_depth_test(true);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
immUnbindProgram();
@@ -666,7 +666,7 @@ static void curve_draw_exec_precalc(wmOperator *op)
selem_prev = selem;
}
scale_px = ((len_3d > 0.0f) && (len_2d > 0.0f)) ? (len_3d / len_2d) : 0.0f;
- float error_threshold = (cps->error_threshold * U.pixelsize) * scale_px;
+ float error_threshold = (cps->error_threshold * U.dpi_fac) * scale_px;
RNA_property_float_set(op->ptr, prop, error_threshold);
}
@@ -685,7 +685,7 @@ static void curve_draw_exec_precalc(wmOperator *op)
}
if (len_squared_v2v2(selem_first->mval, selem_last->mval) <=
- square_f(STROKE_CYCLIC_DIST_PX * U.pixelsize)) {
+ square_f(STROKE_CYCLIC_DIST_PX * U.dpi_fac)) {
use_cyclic = true;
}
}
diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
index 341f43d0662..d4d9f9bf424 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
@@ -195,9 +195,9 @@ static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool
GPU_matrix_push();
GPU_matrix_mul(matrix_final);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
arrow_draw_geom(arrow, select, color);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_matrix_pop();
@@ -207,9 +207,9 @@ static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool
GPU_matrix_push();
GPU_matrix_mul(inter->init_matrix_final);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
arrow_draw_geom(arrow, select, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f});
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_matrix_pop();
}
diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
index c5231b3cd96..13f3903f0b2 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
@@ -195,7 +195,7 @@ static void button2d_draw_intern(const bContext *C,
}
else {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
if (draw_options & ED_GIZMO_BUTTON_SHOW_BACKDROP) {
const float fill_alpha = RNA_float_get(gz->ptr, "backdrop_fill_alpha");
@@ -226,10 +226,10 @@ static void button2d_draw_intern(const bContext *C,
float color_contrast[4];
copy_v3_fl(color_contrast, rgb_to_grayscale(color) < 0.2f ? 1 : 0);
color_contrast[3] = color[3];
- GPU_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color_contrast));
+ GPU_shader_uniform_4f(button->shape_batch[i]->shader, "color", UNPACK4(color_contrast));
}
else {
- GPU_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color));
+ GPU_shader_uniform_4f(button->shape_batch[i]->shader, "color", UNPACK4(color));
}
GPU_batch_draw(button->shape_batch[i]);
@@ -265,7 +265,7 @@ static void button2d_draw_intern(const bContext *C,
UI_icon_draw_alpha(pos[0], pos[1], button->icon, alpha);
GPU_polygon_smooth(true);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
if (need_to_pop) {
@@ -283,9 +283,9 @@ static void gizmo_button2d_draw(const bContext *C, wmGizmo *gz)
{
const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
button2d_draw_intern(C, gz, false, is_highlight);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static int gizmo_button2d_test_select(bContext *C, wmGizmo *gz, const int mval[2])
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
index 406d66dfd8f..be5f488d759 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
@@ -626,14 +626,14 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
/* Handy for quick testing draw (if it's outside bounds). */
if (false) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv((const float[4]){1, 1, 1, 0.5f});
float s = 0.5f;
immRectf(pos, -s, -s, s, s);
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
if (select) {
@@ -722,7 +722,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
float color[4], black[3] = {0, 0, 0};
gizmo_color_get(gz, highlight, color);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
float outline_line_width = gz->line_width + 3.0f;
cage2d_draw_circle_wire(&r, margin, black, transform_flag, draw_options, outline_line_width);
@@ -732,7 +732,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
cage2d_draw_circle_handles(&r, margin, color, transform_flag, true);
cage2d_draw_circle_handles(&r, margin, (const float[3]){0, 0, 0}, transform_flag, false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
else {
BLI_assert(0);
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
index 0bc65fe10a5..644a4247d84 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
@@ -303,14 +303,14 @@ static void gizmo_cage3d_draw_intern(
/* Handy for quick testing draw (if it's outside bounds). */
if (false) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv((const float[4]){1, 1, 1, 0.5f});
float s = 0.5f;
immRectf(pos, -s, -s, s, s);
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
if (select) {
@@ -382,7 +382,7 @@ static void gizmo_cage3d_draw_intern(
float color[4], black[3] = {0, 0, 0};
gizmo_color_get(gz, highlight, color);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
cage3d_draw_circle_wire(
size_real, margin, black, transform_flag, draw_options, gz->line_width + 3.0f);
@@ -395,7 +395,7 @@ static void gizmo_cage3d_draw_intern(
cage3d_draw_circle_handles(rv3d, matrix_final, size_real, margin, color, true, 40);
GPU_polygon_smooth(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
else {
BLI_assert(0);
diff --git a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
index 5d7c3a9e717..e1860d5d0fd 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
@@ -482,9 +482,9 @@ static void gizmo_dial_draw(const bContext *C, wmGizmo *gz)
clip_plane[3] += DIAL_CLIP_BIAS;
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
dial_draw_intern(C, gz, false, is_highlight, clip_plane);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static int gizmo_dial_modal(bContext *C,
diff --git a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
index db57a33f543..ad7036f4460 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c
@@ -207,9 +207,9 @@ static void move3d_draw_intern(const bContext *C,
GPU_matrix_mul(matrix_align);
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
move_geom_draw(gz, color, select, draw_options);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_matrix_pop();
if (gz->interaction_data) {
@@ -220,9 +220,9 @@ static void move3d_draw_intern(const bContext *C,
GPU_matrix_mul(matrix_align);
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
move_geom_draw(gz, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}, select, draw_options);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_matrix_pop();
}
}
@@ -240,9 +240,9 @@ static void gizmo_move_draw(const bContext *C, wmGizmo *gz)
(void)is_modal;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
move3d_draw_intern(C, gz, false, is_highlight);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static int gizmo_move_modal(bContext *C,
diff --git a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c
index 48b2e3348c9..177687b6afd 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c
@@ -96,9 +96,9 @@ static void gizmo_primitive_draw_intern(wmGizmo *gz,
GPU_matrix_push();
GPU_matrix_mul(matrix_final);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
gizmo_primitive_draw_geom(color_inner, color_outer, draw_style);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_matrix_pop();
@@ -112,9 +112,9 @@ static void gizmo_primitive_draw_intern(wmGizmo *gz,
GPU_matrix_push();
GPU_matrix_mul(inter->init_matrix_final);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
gizmo_primitive_draw_geom(color_inner, color_outer, draw_style);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_matrix_pop();
}
diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c
index df479325027..654d1b87918 100644
--- a/source/blender/editors/gpencil/annotate_draw.c
+++ b/source/blender/editors/gpencil/annotate_draw.c
@@ -734,9 +734,7 @@ static void annotation_draw_data(
GPU_line_smooth(true);
/* turn on alpha-blending */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* Do not write to depth (avoid self-occlusion). */
bool prev_depth_mask = GPU_depth_mask_get();
@@ -746,8 +744,8 @@ static void annotation_draw_data(
annotation_draw_data_layers(gpd, offsx, offsy, winx, winy, cfra, dflag);
/* turn off alpha blending, then smooth lines */
- GPU_blend(false); // alpha blending
- GPU_line_smooth(false); // smooth lines
+ GPU_blend(GPU_BLEND_NONE); // alpha blending
+ GPU_line_smooth(false); // smooth lines
GPU_depth_mask(prev_depth_mask);
}
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index 30e4fe0b531..8237e6cfd62 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -1700,9 +1700,7 @@ static void annotation_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_pt
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
GPU_line_smooth(true);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformColor4ub(255, 100, 100, 20);
imm_draw_circle_fill_2d(shdr_pos, x, y, p->radius, 40);
@@ -1730,7 +1728,7 @@ static void annotation_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_pt
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
}
@@ -1768,7 +1766,7 @@ static void annotation_draw_stabilizer(bContext *C, int x, int y, void *p_ptr)
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
GPU_line_smooth(true);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_width(1.25f);
const float color[3] = {1.0f, 0.39f, 0.39f};
@@ -1793,7 +1791,7 @@ static void annotation_draw_stabilizer(bContext *C, int x, int y, void *p_ptr)
immEnd();
/* Returns back all GPU settings */
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
immUnbindProgram();
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 99e98df3397..1bbba6c4b8a 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -3645,7 +3645,6 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
Scene *scene = CTX_data_scene(C);
- Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ARegion *region = CTX_wm_region(C);
int oldframe = (int)DEG_get_ctime(depsgraph);
@@ -3669,7 +3668,7 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op)
if ((mode == GP_REPROJECT_SURFACE) && (cfra_prv != gpf_->framenum)) {
cfra_prv = gpf_->framenum;
CFRA = gpf_->framenum;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
ED_gpencil_stroke_reproject(depsgraph, &gsc, sctx, gpl, gpf_, gps, mode, keep_original);
@@ -3679,7 +3678,7 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op)
/* return frame state and DB to original state */
CFRA = oldframe;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
if (sctx != NULL) {
ED_transform_snap_object_context_destroy(sctx);
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 9d99773348b..ae9146b3a6a 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -252,7 +252,7 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
tgpw.disable_fill = 1;
tgpw.dflag |= (GP_DRAWFILLS_ONLY3D | GP_DRAWFILLS_NOSTATUS);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd);
BLI_assert(gpl_active != NULL);
@@ -371,7 +371,7 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
}
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* draw strokes in offscreen buffer */
diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c
index a6088e31ff8..f4e40c2670f 100644
--- a/source/blender/editors/gpencil/gpencil_mesh.c
+++ b/source/blender/editors/gpencil/gpencil_mesh.c
@@ -246,7 +246,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
/* Move scene to new frame. */
CFRA = i;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
/* Loop all objects in the list. */
LISTBASE_FOREACH (GpBakeOb *, elem, &list) {
@@ -287,7 +287,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
/* Return scene frame state and DB to original state. */
CFRA = oldframe;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
/* Remove unused materials. */
int actcol = ob_gpencil->actcol;
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 680e7b37d31..3f62c3ec8c0 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -2268,9 +2268,7 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr)
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
GPU_line_smooth(true);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformColor4ub(255, 100, 100, 20);
imm_draw_circle_fill_2d(shdr_pos, x, y, p->radius, 40);
@@ -2298,7 +2296,7 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr)
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
}
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 5aae10a5db5..8b77709bacb 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -1760,9 +1760,7 @@ void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y)
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
GPU_line_smooth(true);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformColor4ub(255, 100, 100, 20);
imm_draw_circle_fill_2d(shdr_pos, x, y, radius, 40);
@@ -1790,7 +1788,7 @@ void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y)
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
@@ -1944,7 +1942,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
GPU_line_smooth(true);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* Inner Ring: Color from UI panel */
immUniformColor4f(color[0], color[1], color[2], 0.8f);
@@ -1963,13 +1961,13 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat
immUniformColor4f(darkcolor[0], darkcolor[1], darkcolor[2], 0.8f);
imm_draw_circle_wire_2d(pos, x, y, radius + 1, 40);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
/* Draw line for lazy mouse */
if ((last_mouse_position) && (brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP)) {
GPU_line_smooth(true);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
copy_v3_v3(color, brush->add_col);
immUniformColor4f(color[0], color[1], color[2], 0.8f);
@@ -1981,7 +1979,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat
last_mouse_position[1] + region->winrct.ymin);
immEnd();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
diff --git a/source/blender/editors/include/ED_info.h b/source/blender/editors/include/ED_info.h
index df6b6a20ddc..e3ce494e09a 100644
--- a/source/blender/editors/include/ED_info.h
+++ b/source/blender/editors/include/ED_info.h
@@ -31,8 +31,13 @@ struct Main;
/* info_stats.c */
void ED_info_stats_clear(struct ViewLayer *view_layer);
const char *ED_info_statusbar_string(struct Main *bmain,
- struct bScreen *screen,
- struct bContext *C);
+ struct Scene *scene,
+ struct ViewLayer *view_layer);
+
+const char *ED_info_statistics_string(struct Main *bmain,
+ struct Scene *scene,
+ struct ViewLayer *view_layer);
+
void ED_info_draw_stats(
struct Main *bmain, Scene *scene, ViewLayer *view_layer, int x, int *y, int height);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 29fe766b2d0..ad46dada0c9 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -187,11 +187,7 @@ void ED_area_newspace(struct bContext *C, ScrArea *area, int type, const bool sk
void ED_area_prevspace(struct bContext *C, ScrArea *area);
void ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2);
int ED_area_headersize(void);
-int ED_area_header_alignment_or_fallback(const ScrArea *area, int fallback);
-int ED_area_header_alignment(const ScrArea *area);
int ED_area_footersize(void);
-int ED_area_footer_alignment_or_fallback(const ScrArea *area, int fallback);
-int ED_area_footer_alignment(const ScrArea *area);
int ED_area_global_size_y(const ScrArea *area);
int ED_area_global_min_size_y(const ScrArea *area);
int ED_area_global_max_size_y(const ScrArea *area);
diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h
index c3abde479f1..bfc46534b99 100644
--- a/source/blender/editors/include/ED_sculpt.h
+++ b/source/blender/editors/include/ED_sculpt.h
@@ -53,6 +53,10 @@ void ED_sculpt_undosys_type(struct UndoType *ut);
void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name);
void ED_sculpt_undo_geometry_end(struct Object *ob);
+/* Face sets. */
+int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh);
+void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, const int new_id);
+
/* Undo for changes happening on a base mesh for multires sculpting.
* if there is no multires sculpt active regular undo is used. */
void ED_sculpt_undo_push_multires_mesh_begin(struct bContext *C, const char *str);
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index 1bd9b3063bd..d14731b81b7 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -121,9 +121,9 @@ void UI_view2d_curRect_reset(struct View2D *v2d);
void UI_view2d_sync(struct bScreen *screen, struct ScrArea *area, struct View2D *v2dcur, int flag);
/* Perform all required updates after `v2d->cur` as been modified.
- * This includes like validation view validation (UI_view2d_curRect_validate).
+ * This includes like validation view validation (#UI_view2d_curRect_validate).
*
- * Current lintent is to use it from user code, such as view navigation and zoom operations. */
+ * Current intent is to use it from user code, such as view navigation and zoom operations. */
void UI_view2d_curRect_changed(const struct bContext *C, struct View2D *v2d);
void UI_view2d_totRect_set(struct View2D *v2d, int width, int height);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 2ee1ecccd56..e04531bb1dd 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -44,6 +44,8 @@
#include "BLI_utildefines.h"
+#include "BLO_readfile.h"
+
#include "BKE_animsys.h"
#include "BKE_context.h"
#include "BKE_idprop.h"
@@ -69,7 +71,9 @@
#include "RNA_access.h"
-#include "BPY_extern.h"
+#ifdef WITH_PYTHON
+# include "BPY_extern_run.h"
+#endif
#include "ED_numinput.h"
#include "ED_screen.h"
@@ -354,9 +358,7 @@ void ui_region_winrct_get_no_margin(const struct ARegion *region, struct rcti *r
void UI_block_translate(uiBlock *block, int x, int y)
{
- uiBut *but;
-
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
BLI_rctf_translate(&but->rect, x, y);
}
@@ -366,12 +368,13 @@ void UI_block_translate(uiBlock *block, int x, int y)
static void ui_block_bounds_calc_text(uiBlock *block, float offset)
{
const uiStyle *style = UI_style_get();
- uiBut *bt, *init_col_bt, *col_bt;
+ uiBut *col_bt;
int i = 0, j, x1addval = offset;
UI_fontstyle_set(&style->widget);
- for (init_col_bt = bt = block->buttons.first; bt; bt = bt->next) {
+ uiBut *init_col_bt = block->buttons.first;
+ LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
if (!ELEM(bt->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR_SPACER)) {
j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr));
@@ -407,7 +410,6 @@ static void ui_block_bounds_calc_text(uiBlock *block, float offset)
void ui_block_bounds_calc(uiBlock *block)
{
- uiBut *bt;
int xof;
if (BLI_listbase_is_empty(&block->buttons)) {
@@ -422,7 +424,7 @@ void ui_block_bounds_calc(uiBlock *block)
BLI_rctf_init_minmax(&block->rect);
- for (bt = block->buttons.first; bt; bt = bt->next) {
+ LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
BLI_rctf_union(&block->rect, &bt->rect);
}
@@ -435,7 +437,7 @@ void ui_block_bounds_calc(uiBlock *block)
block->rect.xmax = block->rect.xmin + max_ff(BLI_rctf_size_x(&block->rect), block->minbounds);
/* hardcoded exception... but that one is annoying with larger safety */
- bt = block->buttons.first;
+ uiBut *bt = block->buttons.first;
if (bt && STREQLEN(bt->str, "ERROR", 5)) {
xof = 10;
}
@@ -697,9 +699,10 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new)
{
- uiBut *but_old;
- for (but_old = block_old->buttons.first; but_old; but_old = but_old->next) {
- if (ui_but_equals_old(but_new, but_old)) {
+ uiBut *but_old = NULL;
+ LISTBASE_FOREACH (uiBut *, but, &block_old->buttons) {
+ if (ui_but_equals_old(but_new, but)) {
+ but_old = but;
break;
}
}
@@ -707,9 +710,10 @@ uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new)
}
uiBut *ui_but_find_new(uiBlock *block_new, const uiBut *but_old)
{
- uiBut *but_new;
- for (but_new = block_new->buttons.first; but_new; but_new = but_new->next) {
- if (ui_but_equals_old(but_new, but_old)) {
+ uiBut *but_new = NULL;
+ LISTBASE_FOREACH (uiBut *, but, &block_new->buttons) {
+ if (ui_but_equals_old(but, but_old)) {
+ but_new = but;
break;
}
}
@@ -1461,7 +1465,6 @@ static void ui_but_pie_direction_string(uiBut *but, char *buf, int size)
static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
{
- uiBut *but;
char buf[128];
BLI_assert(block->flag & (UI_BLOCK_LOOP | UI_BLOCK_SHOW_SHORTCUT_ALWAYS));
@@ -1475,7 +1478,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
}
if (block->flag & UI_BLOCK_RADIAL) {
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->pie_dir != UI_RADIAL_NONE) {
ui_but_pie_direction_string(but, buf, sizeof(buf));
ui_but_add_shortcut(but, buf, false);
@@ -1483,7 +1486,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
}
}
else {
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (block->flag & UI_BLOCK_SHOW_SHORTCUT_ALWAYS) {
/* Skip icon-only buttons (as used in the toolbar). */
if (but->drawstr[0] == '\0') {
@@ -1571,10 +1574,7 @@ static void ui_but_extra_operator_icon_free(uiButExtraOpIcon *extra_icon)
void ui_but_extra_operator_icons_free(uiBut *but)
{
-
- for (uiButExtraOpIcon *op_icon = but->extra_op_icons.first, *op_icon_next; op_icon;
- op_icon = op_icon_next) {
- op_icon_next = op_icon->next;
+ LISTBASE_FOREACH_MUTABLE (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) {
ui_but_extra_operator_icon_free(op_icon);
}
BLI_listbase_clear(&but->extra_op_icons);
@@ -1706,7 +1706,6 @@ static void ui_but_predefined_extra_operator_icons_add(uiBut *but)
void UI_block_update_from_old(const bContext *C, uiBlock *block)
{
uiBut *but_old;
- uiBut *but;
if (!block->oldblock) {
return;
@@ -1718,7 +1717,7 @@ void UI_block_update_from_old(const bContext *C, uiBlock *block)
UI_butstore_update(block);
}
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (ui_but_update_from_old_block(C, block, &but, &but_old)) {
ui_but_update(but);
@@ -1743,7 +1742,6 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
Scene *scene = CTX_data_scene(C);
ARegion *region = CTX_wm_region(C);
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- uiBut *but;
BLI_assert(block->active);
@@ -1753,7 +1751,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
* on matching buttons, we need this to make button event handling non
* blocking, while still allowing buttons to be remade each redraw as it
* is expected by blender code */
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
/* temp? Proper check for graying out */
if (but->optype) {
wmOperatorType *ot = but->optype;
@@ -1873,7 +1871,6 @@ void UI_block_draw(const bContext *C, uiBlock *block)
{
uiStyle style = *UI_style_get_dpi(); /* XXX pass on as arg */
ARegion *region;
- uiBut *but;
rcti rect;
/* get menu region or area region */
@@ -1887,8 +1884,7 @@ void UI_block_draw(const bContext *C, uiBlock *block)
}
/* we set this only once */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
/* scale fonts */
ui_fontscale(&style.paneltitle.points, block->aspect);
@@ -1939,7 +1935,7 @@ void UI_block_draw(const bContext *C, uiBlock *block)
UI_widgetbase_draw_cache_begin();
/* widgets */
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (!(but->flag & (UI_HIDDEN | UI_SCROLLED))) {
ui_but_to_pixelrect(&rect, region, block, but);
@@ -2505,17 +2501,18 @@ int ui_but_string_get_max_length(uiBut *but)
uiBut *ui_but_drag_multi_edit_get(uiBut *but)
{
- uiBut *but_iter;
+ uiBut *return_but = NULL;
BLI_assert(but->flag & UI_BUT_DRAG_MULTI);
- for (but_iter = but->block->buttons.first; but_iter; but_iter = but_iter->next) {
+ LISTBASE_FOREACH (uiBut *, but_iter, &but->block->buttons) {
if (but_iter->editstr) {
+ return_but = but_iter;
break;
}
}
- return but_iter;
+ return return_but;
}
static double ui_get_but_scale_unit(uiBut *but, double value)
@@ -2812,7 +2809,7 @@ char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size)
}
/**
- * Report a generic error prefix when evaluating a string with #BPY_execute_string_as_number
+ * Report a generic error prefix when evaluating a string with #BPY_run_string_as_number
* as the Python error on it's own doesn't provide enough context.
*/
#define UI_NUMBER_EVAL_ERROR_PREFIX IFACE_("Error evaluating number, see Info editor for details")
@@ -2837,7 +2834,7 @@ static bool ui_number_from_string(bContext *C, const char *str, double *r_value)
{
bool ok;
#ifdef WITH_PYTHON
- ok = BPY_execute_string_as_number(C, NULL, str, UI_NUMBER_EVAL_ERROR_PREFIX, r_value);
+ ok = BPY_run_string_as_number(C, NULL, str, UI_NUMBER_EVAL_ERROR_PREFIX, r_value);
#else
UNUSED_VARS(C);
*r_value = atof(str);
@@ -3375,11 +3372,7 @@ void UI_blocklist_free(const bContext *C, ListBase *lb)
void UI_blocklist_free_inactive(const bContext *C, ListBase *lb)
{
- uiBlock *block, *nextblock;
-
- for (block = lb->first; block; block = nextblock) {
- nextblock = block->next;
-
+ LISTBASE_FOREACH_MUTABLE (uiBlock *, block, lb) {
if (!block->handle) {
if (!block->active) {
BLI_remlink(lb, block);
@@ -5953,10 +5946,9 @@ uiBut *uiDefIconTextButO(uiBlock *block,
int UI_blocklist_min_y_get(ListBase *lb)
{
- uiBlock *block;
int min = 0;
- for (block = lb->first; block; block = block->next) {
+ LISTBASE_FOREACH (uiBlock *, block, lb) {
if (block == lb->first || block->rect.ymin < min) {
min = block->rect.ymin;
}
@@ -5973,7 +5965,6 @@ void UI_block_direction_set(uiBlock *block, char direction)
/* this call escapes if there's alignment flags */
void UI_block_order_flip(uiBlock *block)
{
- uiBut *but;
float centy, miny = 10000, maxy = -10000;
if (U.uiflag & USER_MENUFIXEDORDER) {
@@ -5983,7 +5974,7 @@ void UI_block_order_flip(uiBlock *block)
return;
}
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->drawflag & UI_BUT_ALIGN) {
return;
}
@@ -5996,7 +5987,7 @@ void UI_block_order_flip(uiBlock *block)
}
/* mirror trick */
centy = (miny + maxy) / 2.0f;
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
but->rect.ymin = centy - (but->rect.ymin - centy);
but->rect.ymax = centy - (but->rect.ymax - centy);
SWAP(float, but->rect.ymin, but->rect.ymax);
@@ -6971,6 +6962,8 @@ void UI_init_userdef(Main *bmain)
/* fix saved themes */
init_userdef_do_versions(bmain);
uiStyleInit();
+
+ BLO_sanitize_experimental_features_userpref_blend(&U);
}
void UI_reinit_font(void)
diff --git a/source/blender/editors/interface/interface_align.c b/source/blender/editors/interface/interface_align.c
index 4981ef111e0..e92adc8a2ec 100644
--- a/source/blender/editors/interface/interface_align.c
+++ b/source/blender/editors/interface/interface_align.c
@@ -24,6 +24,7 @@
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_rect.h"
@@ -385,7 +386,6 @@ static void ui_block_align_but_to_region(uiBut *but, const ARegion *region)
*/
void ui_block_align_calc(uiBlock *block, const ARegion *region)
{
- uiBut *but;
int num_buttons = 0;
const int sides_to_ui_but_align_flags[4] = SIDE_TO_UI_BUT_ALIGN;
@@ -398,7 +398,7 @@ void ui_block_align_calc(uiBlock *block, const ARegion *region)
/* First loop: we count number of buttons belonging to an align group,
* and clear their align flag.
* Tabs get some special treatment here, they get aligned to region border. */
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
/* special case: tabs need to be aligned to a region border, drawflag tells which one */
if (but->type == UI_BTYPE_TAB) {
ui_block_align_but_to_region(but, region);
@@ -431,7 +431,8 @@ void ui_block_align_calc(uiBlock *block, const ARegion *region)
memset(butal_array, 0, sizeof(*butal_array) * (size_t)num_buttons);
/* Second loop: we initialize our ButAlign data for each button. */
- for (but = block->buttons.first, butal = butal_array; but; but = but->next) {
+ butal = butal_array;
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->alignnr != 0) {
butal->but = but;
butal->borders[LEFT] = &but->rect.xmin;
@@ -726,11 +727,10 @@ static void ui_block_align_calc_but(uiBut *first, short nr)
void ui_block_align_calc(uiBlock *block, const struct ARegion *UNUSED(region))
{
- uiBut *but;
short nr;
/* align buttons with same align nr */
- for (but = block->buttons.first; but;) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->alignnr) {
nr = but->alignnr;
ui_block_align_calc_but(but, nr);
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 46876fca9a5..59178e209db 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -47,7 +47,10 @@
#include "RNA_access.h"
-#include "BPY_extern.h"
+#ifdef WITH_PYTHON
+# include "BPY_extern.h"
+# include "BPY_extern_run.h"
+#endif
#include "WM_api.h"
#include "WM_types.h"
@@ -407,7 +410,7 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
"'%s').label",
idname);
char *expr_result = NULL;
- if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
+ if (BPY_run_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
STRNCPY(drawstr, expr_result);
MEM_freeN(expr_result);
}
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 6cd274c8b15..ba878be3dc7 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -161,13 +161,13 @@ void UI_draw_roundbox_aa(
GPUBatch *batch = ui_batch_roundbox_widget_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_batch_draw(batch);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
void UI_draw_roundbox_4fv(
@@ -290,13 +290,13 @@ void UI_draw_roundbox_4fv(
GPUBatch *batch = ui_batch_roundbox_widget_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_batch_draw(batch);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
#if 0
@@ -479,14 +479,14 @@ void UI_draw_roundbox_shade_x(bool filled,
.alpha_discard = 1.0f,
};
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUBatch *batch = ui_batch_roundbox_widget_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
- GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params);
GPU_batch_draw(batch);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
#if 0 /* unused */
@@ -748,13 +748,12 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region),
# if 0
/* prevent drawing outside widget area */
int scissor[4];
- GPU_scissor_get_i(scissor);
+ GPU_scissor_get(scissor);
GPU_scissor(rect->xmin, rect->ymin, w, h);
# endif
- GPU_blend(true);
/* Combine with premultiplied alpha. */
- GPU_blend_set_func_separate(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA_PREMULT);
if (w != ibuf->x || h != ibuf->y) {
/* We scale the bitmap, rather than have OGL do a worse job. */
@@ -780,10 +779,7 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region),
1.0f,
col);
- GPU_blend(false);
- /* Reset default. */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_NONE);
# if 0
// restore scissortest
@@ -830,13 +826,9 @@ void UI_draw_safe_areas(uint pos,
}
}
-static void draw_scope_end(const rctf *rect, GLint *scissor)
+static void draw_scope_end(const rctf *rect)
{
- /* Restore scissor test. */
- GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]);
-
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
/* outline */
UI_draw_roundbox_corner_set(UI_CNR_ALL);
@@ -866,7 +858,7 @@ static void histogram_draw_one(float r,
}
GPU_line_smooth(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE, GPU_ONE, GPU_ONE);
+ GPU_blend(GPU_BLEND_ADDITIVE);
immUniformColor4fv(color);
@@ -896,8 +888,7 @@ static void histogram_draw_one(float r,
/* curve outline */
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
immBegin(GPU_PRIM_LINE_STRIP, res);
for (int i = 0; i < res; i++) {
float x2 = x + i * (w / (float)res);
@@ -930,9 +921,7 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region),
float w = BLI_rctf_size_x(&rect);
float h = BLI_rctf_size_y(&rect) * hist->ymax;
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
float color[4];
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
@@ -942,7 +931,7 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region),
/* need scissor test, histogram can draw outside of boundary */
int scissor[4];
- GPU_scissor_get_i(scissor);
+ GPU_scissor_get(scissor);
GPU_scissor((rect.xmin - 1),
(rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
@@ -999,8 +988,11 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region),
immUnbindProgram();
+ /* Restore scissor test. */
+ GPU_scissor(UNPACK4(scissor));
+
/* outline */
- draw_scope_end(&rect, scissor);
+ draw_scope_end(&rect);
}
#undef HISTOGRAM_TOT_GRID_LINES
@@ -1071,9 +1063,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region),
/* Flush text cache before changing scissors. */
BLF_batch_draw_flush();
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
float color[4];
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
@@ -1082,7 +1072,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region),
true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
/* need scissor test, waveform can draw outside of boundary */
- GPU_scissor_get_i(scissor);
+ GPU_scissor_get(scissor);
GPU_scissor((rect.xmin - 1),
(rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
@@ -1100,9 +1090,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region),
/* Flush text cache before drawing things on top. */
BLF_batch_draw_flush();
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -1167,7 +1155,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region),
}
if (scopes->ok && scopes->waveform_1 != NULL) {
- GPU_blend_set_func(GPU_ONE, GPU_ONE);
+ GPU_blend(GPU_BLEND_ADDITIVE);
GPU_point_size(1.0);
/* LUMA (1 channel) */
@@ -1257,10 +1245,13 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region),
immUnbindProgram();
+ /* Restore scissor test. */
+ GPU_scissor(UNPACK4(scissor));
+
/* outline */
- draw_scope_end(&rect, scissor);
+ draw_scope_end(&rect);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static float polar_to_x(float center, float diam, float ampli, float angle)
@@ -1401,9 +1392,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region),
float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha;
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
float color[4];
UI_GetThemeColor4fv(TH_PREVIEW_BACK, color);
@@ -1413,7 +1402,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region),
/* need scissor test, hvectorscope can draw outside of boundary */
int scissor[4];
- GPU_scissor_get_i(scissor);
+ GPU_scissor_get(scissor);
GPU_scissor((rect.xmin - 1),
(rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
@@ -1467,7 +1456,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region),
/* pixel point cloud */
const float col[3] = {alpha, alpha, alpha};
- GPU_blend_set_func(GPU_ONE, GPU_ONE);
+ GPU_blend(GPU_BLEND_ADDITIVE);
GPU_point_size(1.0);
GPU_matrix_push();
@@ -1481,10 +1470,12 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region),
immUnbindProgram();
+ /* Restore scissor test. */
+ GPU_scissor(UNPACK4(scissor));
/* outline */
- draw_scope_end(&rect, scissor);
+ draw_scope_end(&rect);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void ui_draw_colorband_handle_tri_hlight(
@@ -1595,7 +1586,7 @@ static void ui_draw_colorband_handle(uint shdr_pos,
shdr_pos, x - half_width, y1 - 1, x + half_width, y1 + height, false);
/* draw all triangles blended */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width, half_width, true);
@@ -1619,7 +1610,7 @@ static void ui_draw_colorband_handle(uint shdr_pos,
immUniformColor3ub(0, 0, 0);
ui_draw_colorband_handle_tri_hlight(shdr_pos, x, y1 + height, half_width, half_width);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUniformColor3ub(128, 128, 128);
ui_draw_colorband_handle_box(
@@ -1677,7 +1668,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
/* layer: color ramp */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
CBData *cbd = coba->data;
@@ -1725,7 +1716,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* New format */
format = immVertexFormat();
@@ -1737,7 +1728,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const
imm_draw_box_wire_2d(pos_id, x1, y1, x1 + sizex, rect->ymax);
/* layer: box outline */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
immBegin(GPU_PRIM_LINES, 2);
@@ -1752,7 +1743,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const
immVertex2f(pos_id, x1 + sizex, y1 - 1);
immEnd();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* layer: draw handles */
for (int a = 0; a < coba->tot; a++, cbd++) {
@@ -1817,10 +1808,10 @@ void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rec
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor3ubv(wcol->inner);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, 1.0f, 32);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
if (use_project_matrix) {
@@ -1917,7 +1908,7 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol,
/* need scissor test, curve can draw outside of boundary */
int scissor[4];
- GPU_scissor_get_i(scissor);
+ GPU_scissor_get(scissor);
rcti scissor_new = {
.xmin = rect->xmin,
.ymin = rect->ymin,
@@ -1957,13 +1948,11 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol,
if (but->a1 == UI_GRAD_H) {
/* grid, hsv uses different grid */
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
ARRAY_SET_ITEMS(color_backdrop, 0, 0, 0, 48.0 / 255.0);
immUniformColor4fv(color_backdrop);
ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
else {
if (cumap->flag & CUMA_DO_CLIP) {
@@ -2076,7 +2065,7 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol,
}
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* Curve filled. */
immUniformColor3ubvAlpha(wcol->item, 128);
@@ -2109,7 +2098,7 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol,
/* Reset state for fill & line. */
GPU_line_smooth(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();
/* The points, use aspect to make them visible on edges. */
@@ -2194,7 +2183,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
/* Test needed because path can draw outside of boundary. */
int scissor[4];
- GPU_scissor_get_i(scissor);
+ GPU_scissor_get(scissor);
rcti scissor_new = {
.xmin = rect->xmin,
.ymin = rect->ymin,
@@ -2293,7 +2282,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
/* Draw the triangles for the profile fill. */
immUniformColor3ubvAlpha((const uchar *)wcol->item, 128);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_polygon_smooth(false);
immBegin(GPU_PRIM_TRIS, 3 * tot_triangles);
for (i = 0; i < tot_triangles; i++) {
@@ -2381,7 +2370,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
/* Draw the control points. */
GPU_line_smooth(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_point_size(max_ff(3.0f, min_ff(UI_DPI_FAC / but->block->aspect * 5.0f, 5.0f)));
immBegin(GPU_PRIM_POINTS, tot_points);
for (i = 0; i < tot_points; i++) {
@@ -2395,7 +2384,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
/* Draw the handle points. */
if (selected_free_points > 0) {
GPU_line_smooth(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_point_size(max_ff(2.0f, min_ff(UI_DPI_FAC / but->block->aspect * 4.0f, 4.0f)));
immBegin(GPU_PRIM_POINTS, selected_free_points * 2);
for (i = 0; i < tot_points; i++) {
@@ -2462,13 +2451,11 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
int width = BLI_rctf_size_x(&rect) + 1;
int height = BLI_rctf_size_y(&rect);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
/* need scissor test, preview image can draw outside of boundary */
int scissor[4];
- GPU_scissor_get_i(scissor);
+ GPU_scissor_get(scissor);
GPU_scissor((rect.xmin - 1),
(rect.ymin - 1),
(rect.xmax + 1) - (rect.xmin - 1),
@@ -2593,10 +2580,12 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
}
+ /* Restore scissor test. */
+ GPU_scissor(UNPACK4(scissor));
/* outline */
- draw_scope_end(&rect, scissor);
+ draw_scope_end(&rect);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* ****************************************************** */
@@ -2677,7 +2666,7 @@ static void ui_shadowbox(uint pos,
void UI_draw_box_shadow(uchar alpha, float minx, float miny, float maxx, float maxy)
{
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -2697,7 +2686,7 @@ void UI_draw_box_shadow(uchar alpha, float minx, float miny, float maxx, float m
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
void ui_draw_dropshadow(
@@ -2723,7 +2712,7 @@ void ui_draw_dropshadow(
a = i * aspect;
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
const float dalpha = alpha * 2.0f / 255.0f;
float calpha = dalpha;
float visibility = 1.0f;
@@ -2760,7 +2749,7 @@ void ui_draw_dropshadow(
GPUBatch *batch = ui_batch_roundbox_shadow_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW);
- GPU_batch_uniform_4fv_array(batch, "parameters", 4, (float *)&widget_params);
+ GPU_batch_uniform_4fv_array(batch, "parameters", 4, (float(*)[4]) & widget_params);
GPU_batch_uniform_1f(batch, "alpha", 1.0f - visibility);
GPU_batch_draw(batch);
@@ -2774,5 +2763,5 @@ void ui_draw_dropshadow(
radius + 0.5f,
color);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 455c4fd5073..77cd3e00f3c 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -874,7 +874,7 @@ static void ui_apply_but_autokey(bContext *C, uiBut *but)
static void ui_apply_but_funcs_after(bContext *C)
{
- uiAfterFunc *afterf, after;
+ uiAfterFunc after;
PointerRNA opptr;
ListBase funcs;
@@ -882,7 +882,7 @@ static void ui_apply_but_funcs_after(bContext *C)
funcs = UIAfterFuncs;
BLI_listbase_clear(&UIAfterFuncs);
- for (afterf = funcs.first; afterf; afterf = after.next) {
+ LISTBASE_FOREACH_MUTABLE (uiAfterFunc *, afterf, &funcs) {
after = *afterf; /* copy to avoid memleak on exit() */
BLI_freelinkN(&funcs, afterf);
@@ -1009,14 +1009,12 @@ static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data)
static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data)
{
- uiBut *bt;
-
ui_but_value_set(but, but->hardmax);
ui_apply_but_func(C, but);
/* states of other row buttons */
- for (bt = block->buttons.first; bt; bt = bt->next) {
+ LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
if (bt != but && bt->poin == but->poin && ELEM(bt->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
ui_but_update_edited(bt);
}
@@ -1180,9 +1178,7 @@ static uiButMultiState *ui_multibut_lookup(uiHandleButtonData *data, const uiBut
static void ui_multibut_restore(bContext *C, uiHandleButtonData *data, uiBlock *block)
{
- uiBut *but;
-
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->flag & UI_BUT_DRAG_MULTI) {
uiButMultiState *mbut_state = ui_multibut_lookup(data, but);
if (mbut_state) {
@@ -1235,7 +1231,6 @@ static bool ui_multibut_states_tag(uiBut *but_active,
uiHandleButtonData *data,
const wmEvent *event)
{
- uiBut *but;
float seg[2][2];
bool changed = false;
@@ -1253,7 +1248,7 @@ static bool ui_multibut_states_tag(uiBut *but_active,
data->multi_data.has_mbuts = false;
/* follow ui_but_find_mouse_over_ex logic */
- for (but = but_active->block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &but_active->block->buttons) {
bool drag_prev = false;
bool drag_curr = false;
@@ -1318,12 +1313,11 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl
const double value_delta = data->value - data->origvalue;
const double value_scale = data->multi_data.is_proportional ? (data->value / data->origvalue) :
0.0;
- uiBut *but;
BLI_assert(data->multi_data.init == BUTTON_MULTI_INIT_ENABLE);
BLI_assert(data->multi_data.skip == false);
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->flag & UI_BUT_DRAG_MULTI) {
/* mbut_states for delta */
uiButMultiState *mbut_state = ui_multibut_lookup(data, but);
@@ -1447,18 +1441,15 @@ static bool ui_drag_toggle_set_xy_xy(
/* popups such as layers won't re-evaluate on redraw */
const bool do_check = (region->regiontype == RGN_TYPE_TEMPORARY);
bool changed = false;
- uiBlock *block;
-
- for (block = region->uiblocks.first; block; block = block->next) {
- uiBut *but;
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
float xy_a_block[2] = {UNPACK2(xy_src)};
float xy_b_block[2] = {UNPACK2(xy_dst)};
ui_window_to_block_fl(region, block, &xy_a_block[0], &xy_a_block[1]);
ui_window_to_block_fl(region, block, &xy_b_block[0], &xy_b_block[1]);
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
/* Note: ctrl is always true here because (at least for now)
* we always want to consider text control in this case, even when not embossed. */
if (ui_but_is_interactive(but, true)) {
@@ -2246,10 +2237,9 @@ static void ui_apply_but(
/* only call if event type is EVT_DROP */
static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleButtonData *data)
{
- wmDrag *wmd;
ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */
- for (wmd = drags->first; wmd; wmd = wmd->next) {
+ LISTBASE_FOREACH (wmDrag *, wmd, drags) {
if (wmd->type == WM_DRAG_ID) {
/* align these types with UI_but_active_drop_name */
if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
@@ -4178,7 +4168,7 @@ static uiButExtraOpIcon *ui_but_extra_operator_icon_mouse_over_get(uiBut *but,
}
/* Inverse order, from right to left. */
- for (uiButExtraOpIcon *op_icon = but->extra_op_icons.last; op_icon; op_icon = op_icon->prev) {
+ LISTBASE_FOREACH_BACKWARD (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) {
if ((x > (xmax - icon_size)) && x < xmax) {
return op_icon;
}
@@ -4845,7 +4835,7 @@ static bool ui_numedit_but_NUM(uiBut *but,
if (is_float == false) {
/* at minimum, moving cursor 2 pixels should change an int button. */
- CLAMP_MIN(non_linear_scale, 0.5f * U.pixelsize);
+ CLAMP_MIN(non_linear_scale, 0.5f * UI_DPI_FAC);
}
data->dragf += (((float)(mx - data->draglastx)) / deler) * non_linear_scale;
@@ -7777,15 +7767,13 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
static void ui_blocks_set_tooltips(ARegion *region, const bool enable)
{
- uiBlock *block;
-
if (!region) {
return;
}
/* we disabled buttons when when they were already shown, and
* re-enable them on mouse move */
- for (block = region->uiblocks.first; block; block = block->next) {
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
block->tooltipdisabled = !enable;
}
}
@@ -8164,7 +8152,6 @@ static void button_activate_exit(
{
wmWindow *win = data->window;
uiBlock *block = but->block;
- uiBut *bt;
if (but->type == UI_BTYPE_GRIP) {
WM_cursor_modal_restore(win);
@@ -8182,7 +8169,7 @@ static void button_activate_exit(
#ifdef USE_DRAG_MULTINUM
if (data->multi_data.has_mbuts) {
- for (bt = block->buttons.first; bt; bt = bt->next) {
+ LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
if (bt->flag & UI_BUT_DRAG_MULTI) {
bt->flag &= ~UI_BUT_DRAG_MULTI;
@@ -8238,12 +8225,12 @@ static void button_activate_exit(
}
/* disable tooltips until mousemove + last active flag */
- for (block = data->region->uiblocks.first; block; block = block->next) {
- for (bt = block->buttons.first; bt; bt = bt->next) {
+ LISTBASE_FOREACH (uiBlock *, block_iter, &data->region->uiblocks) {
+ LISTBASE_FOREACH (uiBut *, bt, &block_iter->buttons) {
bt->flag &= ~UI_BUT_LAST_ACTIVE;
}
- block->tooltipdisabled = 1;
+ block_iter->tooltipdisabled = 1;
}
ui_blocks_set_tooltips(data->region, false);
@@ -8308,12 +8295,11 @@ static uiBut *ui_context_button_active(ARegion *region, bool (*but_check_cb)(uiB
uiBut *but_found = NULL;
while (region) {
- uiBlock *block;
- uiBut *but, *activebut = NULL;
+ uiBut *activebut = NULL;
/* find active button */
- for (block = region->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->active) {
activebut = but;
}
@@ -8436,7 +8422,6 @@ void UI_context_active_but_clear(bContext *C, wmWindow *win, ARegion *region)
wmOperator *UI_context_active_operator_get(const struct bContext *C)
{
ARegion *region_ctx = CTX_wm_region(C);
- uiBlock *block;
/* background mode */
if (region_ctx == NULL) {
@@ -8444,7 +8429,7 @@ wmOperator *UI_context_active_operator_get(const struct bContext *C)
}
/* scan active regions ui */
- for (block = region_ctx->uiblocks.first; block; block = block->next) {
+ LISTBASE_FOREACH (uiBlock *, block, &region_ctx->uiblocks) {
if (block->ui_operator) {
return block->ui_operator;
}
@@ -8453,13 +8438,12 @@ wmOperator *UI_context_active_operator_get(const struct bContext *C)
/* scan popups */
{
bScreen *screen = CTX_wm_screen(C);
- ARegion *region;
- for (region = screen->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) {
if (region == region_ctx) {
continue;
}
- for (block = region->uiblocks.first; block; block = block->next) {
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
if (block->ui_operator) {
return block->ui_operator;
}
@@ -8478,15 +8462,14 @@ void UI_context_update_anim_flag(const bContext *C)
struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
depsgraph, (scene) ? scene->r.cfra : 0.0f);
- uiBlock *block;
- uiBut *but, *activebut;
+ uiBut *activebut;
while (region) {
/* find active button */
activebut = NULL;
- for (block = region->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
ui_but_anim_flag(but, &anim_eval_context);
ui_but_override_flag(CTX_data_main(C), but);
if (UI_but_is_decorator(but)) {
@@ -8529,11 +8512,8 @@ void UI_context_update_anim_flag(const bContext *C)
static uiBut *ui_but_find_open_event(ARegion *region, const wmEvent *event)
{
- uiBlock *block;
- uiBut *but;
-
- for (block = region->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but == event->customdata) {
return but;
}
@@ -10289,10 +10269,8 @@ static int ui_but_pie_menu_apply(bContext *C,
static uiBut *ui_block_pie_dir_activate(uiBlock *block, const wmEvent *event, RadialDirection dir)
{
- uiBut *but;
-
if ((block->flag & UI_BLOCK_NUMSELECT) && event->val == KM_PRESS) {
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->pie_dir == dir && !ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) {
return but;
}
@@ -10324,7 +10302,6 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
{
ARegion *region;
uiBlock *block;
- uiBut *but;
float event_xy[2];
double duration;
bool is_click_style;
@@ -10346,7 +10323,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
is_click_style = (block->pie_data.flags & UI_PIE_CLICK_STYLE);
/* if there's an active modal button, don't check events or outside, except for search menu */
- but = ui_region_find_active_but(region);
+ uiBut *but_active = ui_region_find_active_but(region);
if (menu->scrolltimer == NULL) {
menu->scrolltimer = WM_event_add_timer(
@@ -10364,7 +10341,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
/* Distance from initial point. */
dist = ui_block_calc_pie_segment(block, event_xy);
- if (but && button_modal_state(but->active->state)) {
+ if (but_active && button_modal_state(but_active->active->state)) {
retval = ui_handle_menu_button(C, event, menu);
}
else {
@@ -10386,7 +10363,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
block->pie_data.flags |= UI_PIE_ANIMATION_FINISHED;
}
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->pie_dir != UI_RADIAL_NONE) {
float vec[2];
float center[2];
@@ -10425,7 +10402,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
}
if (len_sq < 1.0f) {
- but = ui_region_find_active_but(menu->region);
+ uiBut *but = ui_region_find_active_but(menu->region);
if (but) {
return ui_but_pie_menu_apply(C, menu, but, true);
@@ -10451,7 +10428,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
block->pie_data.flags |= UI_PIE_CLICK_STYLE;
}
else {
- but = ui_region_find_active_but(menu->region);
+ uiBut *but = ui_region_find_active_but(menu->region);
if (but && (U.pie_menu_confirm > 0) &&
(dist >= U.dpi_fac * (U.pie_menu_threshold + U.pie_menu_confirm))) {
@@ -10536,7 +10513,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
case EVT_ZKEY: {
if ((event->val == KM_PRESS || event->val == KM_DBL_CLICK) &&
!IS_EVENT_MOD(event, shift, ctrl, oskey)) {
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->menu_key == event->type) {
ui_but_pie_button_activate(C, but, menu);
}
@@ -10569,7 +10546,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
ATTR_FALLTHROUGH;
CASE_NUM_TO_DIR(9, UI_RADIAL_NE);
{
- but = ui_block_pie_dir_activate(block, event, num_dir);
+ uiBut *but = ui_block_pie_dir_activate(block, event, num_dir);
retval = ui_but_pie_button_activate(C, but, menu);
break;
}
@@ -11033,26 +11010,28 @@ bool UI_textbutton_activate_rna(const bContext *C,
const void *rna_poin_data,
const char *rna_prop_id)
{
- uiBlock *block;
- uiBut *but = NULL;
+ uiBlock *block_text = NULL;
+ uiBut *but_text = NULL;
- for (block = region->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->type == UI_BTYPE_TEXT) {
if (but->rnaprop && but->rnapoin.data == rna_poin_data) {
if (STREQ(RNA_property_identifier(but->rnaprop), rna_prop_id)) {
+ block_text = block;
+ but_text = but;
break;
}
}
}
}
- if (but) {
+ if (but_text) {
break;
}
}
- if (but) {
- UI_but_active_only(C, region, block, but);
+ if (but_text) {
+ UI_but_active_only(C, region, block_text, but_text);
return true;
}
return false;
@@ -11061,23 +11040,25 @@ bool UI_textbutton_activate_rna(const bContext *C,
bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut)
{
ARegion *region = CTX_wm_region(C);
- uiBlock *block;
- uiBut *but = NULL;
+ uiBlock *block_text = NULL;
+ uiBut *but_text = NULL;
- for (block = region->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but == actbut && but->type == UI_BTYPE_TEXT) {
+ block_text = block;
+ but_text = but;
break;
}
}
- if (but) {
+ if (but_text) {
break;
}
}
- if (but) {
- UI_but_active_only(C, region, block, but);
+ if (but_text) {
+ UI_but_active_only(C, region, block_text, but_text);
return true;
}
return false;
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index a7b7bad2fe6..edf66d82cbc 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1595,7 +1595,7 @@ static void icon_draw_cache_flush_ex(bool only_full_caches)
/* We need to flush widget base first to ensure correct ordering. */
UI_widgetbase_draw_cache_flush();
- GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA_PREMULT);
if (!only_full_caches || g_icon_draw_cache.normal.calls == ICON_DRAW_CACHE_SIZE) {
icon_draw_cache_texture_flush_ex(icongltex.tex[0], &g_icon_draw_cache.normal);
@@ -1605,8 +1605,7 @@ static void icon_draw_cache_flush_ex(bool only_full_caches)
icon_draw_cache_texture_flush_ex(icongltex.tex[1], &g_icon_draw_cache.border);
}
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
}
}
@@ -1620,9 +1619,9 @@ void UI_icon_draw_cache_end(void)
return;
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
icon_draw_cache_flush_ex(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void icon_draw_texture_cached(float x,
@@ -1690,7 +1689,7 @@ static void icon_draw_texture(float x,
/* We need to flush widget base first to ensure correct ordering. */
UI_widgetbase_draw_cache_flush();
- GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA_PREMULT);
float x1, x2, y1, y2;
@@ -1726,8 +1725,7 @@ static void icon_draw_texture(float x,
GPU_texture_unbind(texture);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
}
/* Drawing size for preview images */
@@ -1815,11 +1813,9 @@ static void icon_draw_size(float x,
di->data.geom.inverted = invert;
}
- GPU_blend_set_func_separate(
- GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA_PREMULT);
icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, desaturate);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
}
else if (di->type == ICON_TYPE_EVENT) {
const short event_type = di->data.input.event_type;
@@ -1900,12 +1896,10 @@ static void icon_draw_size(float x,
}
/* Preview images use premultiplied alpha. */
- GPU_blend_set_func_separate(
- GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA_PREMULT);
icon_draw_rect(
x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, desaturate);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
}
}
else if (di->type == ICON_TYPE_GPLAYER) {
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 888cacb64eb..ad76466b67c 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -453,7 +453,7 @@ static uiLayout *ui_item_local_sublayout(uiLayout *test, uiLayout *layout, bool
static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index)
{
wmWindow *win = CTX_wm_window(C);
- uiBut *but = arg_but, *cbut;
+ uiBut *but = arg_but;
PointerRNA *ptr = &but->rnapoin;
PropertyRNA *prop = but->rnaprop;
int i, index = POINTER_AS_INT(arg_index);
@@ -471,7 +471,7 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index)
RNA_property_update(C, ptr, prop);
- for (cbut = but->block->buttons.first; cbut; cbut = cbut->next) {
+ LISTBASE_FOREACH (uiBut *, cbut, &but->block->buttons) {
ui_but_update(cbut);
}
}
@@ -1072,8 +1072,7 @@ void UI_context_active_but_prop_get_filebrowser(const bContext *C,
bool *r_is_userdef)
{
ARegion *region = CTX_wm_menu(C) ? CTX_wm_menu(C) : CTX_wm_region(C);
- uiBlock *block;
- uiBut *but, *prevbut = NULL;
+ uiBut *prevbut = NULL;
memset(r_ptr, 0, sizeof(*r_ptr));
*r_prop = NULL;
@@ -1084,8 +1083,8 @@ void UI_context_active_but_prop_get_filebrowser(const bContext *C,
return;
}
- for (block = region->uiblocks.first; block; block = block->next) {
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but && but->rnapoin.data) {
if (RNA_property_type(but->rnaprop) == PROP_STRING) {
prevbut = but;
@@ -3515,14 +3514,13 @@ void uiItemTabsEnumR_prop(
/* single-row layout */
static void ui_litem_estimate_row(uiLayout *litem)
{
- uiItem *item;
int itemw, itemh;
bool min_size_flag = true;
litem->w = 0;
litem->h = 0;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE);
@@ -3547,7 +3545,7 @@ static int ui_litem_min_width(int itemw)
static void ui_litem_layout_row(uiLayout *litem)
{
- uiItem *item, *last_free_item = NULL;
+ uiItem *last_free_item = NULL;
int x, y, w, tot, totw, neww, newtotw, itemw, minw, itemh, offset;
int fixedw, freew, fixedx, freex, flag = 0, lastw = 0;
float extra_pixel;
@@ -3558,7 +3556,7 @@ static void ui_litem_layout_row(uiLayout *litem)
totw = 0;
tot = 0;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
totw += itemw;
tot++;
@@ -3581,7 +3579,7 @@ static void ui_litem_layout_row(uiLayout *litem)
newtotw = totw;
extra_pixel = 0.0f;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
if (item->flag & UI_ITEM_AUTO_FIXED_SIZE) {
continue;
}
@@ -3633,7 +3631,7 @@ static void ui_litem_layout_row(uiLayout *litem)
extra_pixel = 0.0f;
x = litem->x;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
minw = ui_litem_min_width(itemw);
@@ -3682,7 +3680,7 @@ static void ui_litem_layout_row(uiLayout *litem)
if (extra_pixel > 0 && litem->alignment == UI_LAYOUT_ALIGN_EXPAND && last_free_item &&
last_item && last_item->flag & UI_ITEM_AUTO_FIXED_SIZE) {
ui_item_move(last_free_item, 0, extra_pixel);
- for (item = last_free_item->next; item; item = item->next) {
+ for (uiItem *item = last_free_item->next; item; item = item->next) {
ui_item_move(item, extra_pixel, extra_pixel);
}
}
@@ -3696,14 +3694,13 @@ static void ui_litem_layout_row(uiLayout *litem)
/* single-column layout */
static void ui_litem_estimate_column(uiLayout *litem, bool is_box)
{
- uiItem *item;
int itemw, itemh;
bool min_size_flag = true;
litem->w = 0;
litem->h = 0;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE);
@@ -3723,13 +3720,12 @@ static void ui_litem_estimate_column(uiLayout *litem, bool is_box)
static void ui_litem_layout_column(uiLayout *litem, bool is_box)
{
- uiItem *item;
int itemh, x, y;
x = litem->x;
y = litem->y;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, NULL, &itemh);
y -= itemh;
@@ -3789,7 +3785,6 @@ static bool ui_item_is_radial_drawable(uiButtonItem *bitem)
static void ui_litem_layout_radial(uiLayout *litem)
{
- uiItem *item;
int itemh, itemw, x, y;
int itemnum = 0;
int totitems = 0;
@@ -3807,7 +3802,7 @@ static void ui_litem_layout_radial(uiLayout *litem)
int minx = x, miny = y, maxx = x, maxy = y;
/* first count total items */
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
totitems++;
}
@@ -3815,7 +3810,7 @@ static void ui_litem_layout_radial(uiLayout *litem)
litem->root->block->pie_data.flags |= UI_PIE_DEGREES_RANGE_LARGE;
}
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
/* not all button types are drawn in a radial menu, do filtering here */
if (ui_item_is_radial_displayable(item)) {
RadialDirection dir;
@@ -3965,14 +3960,13 @@ static void ui_litem_estimate_column_flow(uiLayout *litem)
{
const uiStyle *style = litem->root->style;
uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem;
- uiItem *item;
int col, x, y, emh, emy, miny, itemw, itemh, maxw = 0;
int toth, totitem;
/* compute max needed width and total height */
toth = 0;
totitem = 0;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
maxw = MAX2(maxw, itemw);
toth += itemh;
@@ -4004,7 +3998,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem)
/* create column per column */
col = 0;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
y -= itemh + style->buttonspacey;
@@ -4030,14 +4024,13 @@ static void ui_litem_layout_column_flow(uiLayout *litem)
{
const uiStyle *style = litem->root->style;
uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem;
- uiItem *item;
int col, x, y, w, emh, emy, miny, itemw, itemh;
int toth, totitem;
/* compute max needed width and total height */
toth = 0;
totitem = 0;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
toth += itemh;
totitem++;
@@ -4055,7 +4048,7 @@ static void ui_litem_layout_column_flow(uiLayout *litem)
/* create column per column */
col = 0;
w = (litem->w - (flow->totcol - 1) * style->columnspace) / flow->totcol;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
itemw = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, itemw);
@@ -4121,9 +4114,6 @@ static void ui_litem_grid_flow_compute(ListBase *items,
UILayoutGridFlowInput *parameters,
UILayoutGridFlowOutput *results)
{
- uiItem *item;
- int i;
-
float tot_w = 0.0f, tot_h = 0.0f;
float global_avg_w = 0.0f, global_totweight_w = 0.0f;
int global_max_h = 0;
@@ -4163,7 +4153,8 @@ static void ui_litem_grid_flow_compute(ListBase *items,
memset(max_h, 0, sizeof(*max_h) * parameters->tot_rows);
}
- for (i = 0, item = items->first; item; item = item->next, i++) {
+ int i = 0;
+ LISTBASE_FOREACH (uiItem *, item, items) {
int item_w, item_h;
ui_item_size(item, &item_w, &item_h);
@@ -4186,6 +4177,7 @@ static void ui_litem_grid_flow_compute(ListBase *items,
if (results->tot_items) {
(*results->tot_items)++;
}
+ i++;
}
/* Finalize computing of column average sizes */
@@ -4394,10 +4386,8 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem)
static void ui_litem_layout_grid_flow(uiLayout *litem)
{
- int i;
const uiStyle *style = litem->root->style;
uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem;
- uiItem *item;
if (gflow->tot_items == 0) {
litem->w = litem->h = 0;
@@ -4436,7 +4426,8 @@ static void ui_litem_layout_grid_flow(uiLayout *litem)
.heights_array = heights,
}));
- for (item = litem->items.first, i = 0; item; item = item->next, i++) {
+ int i;
+ LISTBASE_FOREACH_INDEX (uiItem *, item, &litem->items, i) {
const int col = gflow->row_major ? i % gflow->tot_columns : i / gflow->tot_rows;
const int row = gflow->row_major ? i / gflow->tot_columns : i % gflow->tot_rows;
int item_w, item_h;
@@ -4459,7 +4450,6 @@ static void ui_litem_layout_grid_flow(uiLayout *litem)
/* free layout */
static void ui_litem_estimate_absolute(uiLayout *litem)
{
- uiItem *item;
int itemx, itemy, itemw, itemh, minx, miny;
minx = 1e6;
@@ -4467,7 +4457,7 @@ static void ui_litem_estimate_absolute(uiLayout *litem)
litem->w = 0;
litem->h = 0;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_offset(item, &itemx, &itemy);
ui_item_size(item, &itemw, &itemh);
@@ -4484,7 +4474,6 @@ static void ui_litem_estimate_absolute(uiLayout *litem)
static void ui_litem_layout_absolute(uiLayout *litem)
{
- uiItem *item;
float scalex = 1.0f, scaley = 1.0f;
int x, y, newx, newy, itemx, itemy, itemh, itemw, minx, miny, totw, toth;
@@ -4493,7 +4482,7 @@ static void ui_litem_layout_absolute(uiLayout *litem)
totw = 0;
toth = 0;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_offset(item, &itemx, &itemy);
ui_item_size(item, &itemw, &itemh);
@@ -4517,7 +4506,7 @@ static void ui_litem_layout_absolute(uiLayout *litem)
x = litem->x;
y = litem->y - scaley * toth;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_offset(item, &itemx, &itemy);
ui_item_size(item, &itemw, &itemh);
@@ -4552,7 +4541,6 @@ static void ui_litem_estimate_split(uiLayout *litem)
static void ui_litem_layout_split(uiLayout *litem)
{
uiLayoutItemSplit *split = (uiLayoutItemSplit *)litem;
- uiItem *item;
float percentage, extra_pixel = 0.0f;
const int tot = BLI_listbase_count(&litem->items);
int itemh, x, y, w, colw = 0;
@@ -4570,7 +4558,7 @@ static void ui_litem_layout_split(uiLayout *litem)
colw = w * percentage;
colw = MAX2(colw, 0);
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, NULL, &itemh);
ui_item_position(item, x, y - itemh, colw, itemh);
@@ -4595,13 +4583,12 @@ static void ui_litem_layout_split(uiLayout *litem)
/* overlap layout */
static void ui_litem_estimate_overlap(uiLayout *litem)
{
- uiItem *item;
int itemw, itemh;
litem->w = 0;
litem->h = 0;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
litem->w = MAX2(itemw, litem->w);
@@ -4611,13 +4598,12 @@ static void ui_litem_estimate_overlap(uiLayout *litem)
static void ui_litem_layout_overlap(uiLayout *litem)
{
- uiItem *item;
int itemw, itemh, x, y;
x = litem->x;
y = litem->y;
- for (item = litem->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &litem->items) {
ui_item_size(item, &itemw, &itemh);
ui_item_position(item, x, y - itemh, litem->w, itemh);
@@ -4775,7 +4761,6 @@ static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type)
uiLayout *uiLayoutRadial(uiLayout *layout)
{
uiLayout *litem;
- uiItem *item;
/* radial layouts are only valid for radial menus */
if (layout->root->type != UI_LAYOUT_PIEMENU) {
@@ -4783,7 +4768,7 @@ uiLayout *uiLayoutRadial(uiLayout *layout)
}
/* only one radial wheel per root layout is allowed, so check and return that, if it exists */
- for (item = layout->root->layout->items.first; item; item = item->next) {
+ LISTBASE_FOREACH (uiItem *, item, &layout->root->layout->items) {
litem = (uiLayout *)item;
if (litem->item.type == ITEM_LAYOUT_RADIAL) {
UI_block_layout_set_current(layout->root->block, litem);
@@ -4813,8 +4798,7 @@ uiLayout *uiLayoutBox(uiLayout *layout)
*/
void ui_layout_list_set_labels_active(uiLayout *layout)
{
- uiButtonItem *bitem;
- for (bitem = layout->items.first; bitem; bitem = bitem->item.next) {
+ LISTBASE_FOREACH (uiButtonItem *, bitem, &layout->items) {
if (bitem->item.type != ITEM_BUTTON) {
ui_layout_list_set_labels_active((uiLayout *)(&bitem->item));
}
@@ -5055,10 +5039,9 @@ int uiLayoutGetEmboss(uiLayout *layout)
static void ui_item_scale(uiLayout *litem, const float scale[2])
{
- uiItem *item;
int x, y, w, h;
- for (item = litem->items.last; item; item = item->prev) {
+ LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) {
if (item->type != ITEM_BUTTON) {
uiLayout *subitem = (uiLayout *)item;
ui_item_scale(subitem, scale);
@@ -5083,12 +5066,10 @@ static void ui_item_scale(uiLayout *litem, const float scale[2])
static void ui_item_estimate(uiItem *item)
{
- uiItem *subitem;
-
if (item->type != ITEM_BUTTON) {
uiLayout *litem = (uiLayout *)item;
- for (subitem = litem->items.first; subitem; subitem = subitem->next) {
+ LISTBASE_FOREACH (uiItem *, subitem, &litem->items) {
ui_item_estimate(subitem);
}
@@ -5146,11 +5127,10 @@ static void ui_item_estimate(uiItem *item)
static void ui_item_align(uiLayout *litem, short nr)
{
- uiItem *item;
uiButtonItem *bitem;
uiLayoutItemBx *box;
- for (item = litem->items.last; item; item = item->prev) {
+ LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) {
if (item->type == ITEM_BUTTON) {
bitem = (uiButtonItem *)item;
#ifndef USE_UIBUT_SPATIAL_ALIGN
@@ -5182,10 +5162,9 @@ static void ui_item_align(uiLayout *litem, short nr)
static void ui_item_flag(uiLayout *litem, int flag)
{
- uiItem *item;
uiButtonItem *bitem;
- for (item = litem->items.last; item; item = item->prev) {
+ LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) {
if (item->type == ITEM_BUTTON) {
bitem = (uiButtonItem *)item;
bitem->but->flag |= flag;
@@ -5198,8 +5177,6 @@ static void ui_item_flag(uiLayout *litem, int flag)
static void ui_item_layout(uiItem *item)
{
- uiItem *subitem;
-
if (item->type != ITEM_BUTTON) {
uiLayout *litem = (uiLayout *)item;
@@ -5252,7 +5229,7 @@ static void ui_item_layout(uiItem *item)
break;
}
- for (subitem = litem->items.first; subitem; subitem = subitem->next) {
+ LISTBASE_FOREACH (uiItem *, subitem, &litem->items) {
if (item->flag & UI_ITEM_BOX_ITEM) {
subitem->flag |= UI_ITEM_BOX_ITEM;
}
@@ -5286,11 +5263,7 @@ static void ui_layout_end(uiBlock *block, uiLayout *layout, int *r_x, int *r_y)
static void ui_layout_free(uiLayout *layout)
{
- uiItem *item, *next;
-
- for (item = layout->items.first; item; item = next) {
- next = item->next;
-
+ LISTBASE_FOREACH_MUTABLE (uiItem *, item, &layout->items) {
if (item->type == ITEM_BUTTON) {
MEM_freeN(item);
}
@@ -5474,8 +5447,6 @@ void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv)
void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y)
{
- uiLayoutRoot *root;
-
BLI_assert(block->active);
if (r_x) {
@@ -5487,7 +5458,7 @@ void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y)
block->curlayout = NULL;
- for (root = block->layouts.first; root; root = root->next) {
+ LISTBASE_FOREACH (uiLayoutRoot *, root, &block->layouts) {
ui_layout_add_padding_button(root);
/* NULL in advance so we don't interfere when adding button */
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 5a49f3e70d0..e47761236ca 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -715,8 +715,7 @@ static void ui_context_selected_bones_via_pose(bContext *C, ListBase *r_lb)
lb = CTX_data_collection_get(C, "selected_pose_bones");
if (!BLI_listbase_is_empty(&lb)) {
- CollectionPointerLink *link;
- for (link = lb.first; link; link = link->next) {
+ LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) {
bPoseChannel *pchan = link->ptr.data;
RNA_pointer_create(link->ptr.owner_id, &RNA_Bone, pchan->bone, &link->ptr);
}
@@ -843,12 +842,10 @@ bool UI_context_copy_to_selected_list(bContext *C,
/* Now filter by type */
if (node) {
- CollectionPointerLink *link, *link_next;
lb = CTX_data_collection_get(C, "selected_nodes");
- for (link = lb.first; link; link = link_next) {
+ LISTBASE_FOREACH_MUTABLE (CollectionPointerLink *, link, &lb) {
bNode *node_data = link->ptr.data;
- link_next = link->next;
if (node_data->type != node->type) {
BLI_remlink(&lb, link);
@@ -876,9 +873,7 @@ bool UI_context_copy_to_selected_list(bContext *C,
/* de-duplicate obdata */
if (!BLI_listbase_is_empty(&lb)) {
- CollectionPointerLink *link, *link_next;
-
- for (link = lb.first; link; link = link->next) {
+ LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) {
Object *ob = (Object *)link->ptr.owner_id;
if (ob->data) {
ID *id_data = ob->data;
@@ -886,10 +881,9 @@ bool UI_context_copy_to_selected_list(bContext *C,
}
}
- for (link = lb.first; link; link = link_next) {
+ LISTBASE_FOREACH_MUTABLE (CollectionPointerLink *, link, &lb) {
Object *ob = (Object *)link->ptr.owner_id;
ID *id_data = ob->data;
- link_next = link->next;
if ((id_data == NULL) || (id_data->tag & LIB_TAG_DOIT) == 0 || ID_IS_LINKED(id_data) ||
(GS(id_data->name) != id_code)) {
@@ -970,12 +964,11 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll)
if (ptr.data && prop) {
char *path = NULL;
bool use_path_from_id;
- CollectionPointerLink *link;
ListBase lb = {NULL};
if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) &&
!BLI_listbase_is_empty(&lb)) {
- for (link = lb.first; link; link = link->next) {
+ LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) {
if (link->ptr.data != ptr.data) {
if (use_path_from_id) {
/* Path relative to ID. */
@@ -1299,13 +1292,14 @@ static int editsource_text_edit(bContext *C,
const int line)
{
struct Main *bmain = CTX_data_main(C);
- Text *text;
+ Text *text = NULL;
/* Developers may wish to copy-paste to an external editor. */
printf("%s:%d\n", filepath, line);
- for (text = bmain->texts.first; text; text = text->id.next) {
- if (text->filepath && BLI_path_cmp(text->filepath, filepath) == 0) {
+ LISTBASE_FOREACH (Text *, text_iter, &bmain->texts) {
+ if (text_iter->filepath && BLI_path_cmp(text_iter->filepath, filepath) == 0) {
+ text = text_iter;
break;
}
}
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index d334007a097..a70bcd208ab 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -1000,7 +1000,7 @@ void ui_draw_aligned_panel(uiStyle *style,
/* Mimick the border between aligned box widgets for the bottom of the header. */
if (!(is_closed_x || is_closed_y)) {
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformColor4ubv(box_wcol->outline);
immRectf(pos, rect->xmin, headrect.ymin - U.pixelsize, rect->xmax, headrect.ymin);
@@ -1013,7 +1013,7 @@ void ui_draw_aligned_panel(uiStyle *style,
rect->xmax,
headrect.ymin - U.pixelsize - 1);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();
}
}
@@ -1025,7 +1025,7 @@ void ui_draw_aligned_panel(uiStyle *style,
float y = headrect.ymax;
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* draw with background color */
immUniformThemeColor(TH_PANEL_HEADER);
@@ -1041,7 +1041,7 @@ void ui_draw_aligned_panel(uiStyle *style,
immEnd();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();
}
@@ -1055,7 +1055,7 @@ void ui_draw_aligned_panel(uiStyle *style,
uchar col_title[4];
panel_title_color_get(show_background, col_title);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_icon_draw_ex(headrect.xmax - ((PNL_ICON * 2.2f) / block->aspect),
headrect.ymin + (5.0f / block->aspect),
(panel->flag & PNL_PIN) ? ICON_PINNED : ICON_UNPINNED,
@@ -1064,7 +1064,7 @@ void ui_draw_aligned_panel(uiStyle *style,
0.0f,
col_title,
false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* horizontal title */
@@ -1134,7 +1134,7 @@ void ui_draw_aligned_panel(uiStyle *style,
}
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* Draw panel backdrop if it wasn't already been drawn by the single opaque round box earlier.
* Note: Sub-panels blend with panels, so they can't be opaque. */
@@ -2366,7 +2366,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active)
/* draw the background */
if (is_alpha) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformColor4ubv(theme_col_tab_bg);
}
else {
@@ -2383,7 +2383,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active)
}
if (is_alpha) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
immUnbindProgram();
@@ -2403,7 +2403,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active)
const bool is_active = STREQ(category_id, category_id_active);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
#ifdef USE_FLAT_INACTIVE
if (is_active)
@@ -2479,7 +2479,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active)
/* main tab title */
BLF_draw(fontid, category_id_draw, category_draw_len);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* tab blackline remaining (last tab) */
pos = GPU_vertformat_attr_add(
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index edb5d51a392..8648a54f7d5 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -276,7 +276,7 @@ uiBut *ui_but_find_mouse_over_ex(ARegion *region, const int x, const int y, cons
float mx = x, my = y;
ui_window_to_block_fl(region, block, &mx, &my);
- for (uiBut *but = block->buttons.last; but; but = but->prev) {
+ LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) {
if (ui_but_is_interactive(but, labeledit)) {
if (but->pie_dir != UI_RADIAL_NONE) {
if (ui_but_isect_pie_seg(block, but)) {
@@ -324,7 +324,7 @@ uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px)
rctf rect_block;
ui_window_to_block_rctf(region, block, &rect_block, &rect_px_fl);
- for (uiBut *but = block->buttons.last; but; but = but->prev) {
+ LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) {
if (ui_but_is_interactive(but, labeledit)) {
/* No pie menu support. */
BLI_assert(but->pie_dir == UI_RADIAL_NONE);
@@ -354,7 +354,7 @@ uiBut *ui_list_find_mouse_over_ex(ARegion *region, int x, int y)
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
float mx = x, my = y;
ui_window_to_block_fl(region, block, &mx, &my);
- for (uiBut *but = block->buttons.last; but; but = but->prev) {
+ LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) {
if (but->type == UI_BTYPE_LISTBOX && ui_but_contains_pt(but, mx, my)) {
return but;
}
@@ -399,14 +399,10 @@ uiBut *ui_but_next(uiBut *but)
uiBut *ui_but_first(uiBlock *block)
{
- uiBut *but;
-
- but = block->buttons.first;
- while (but) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (ui_but_is_editable(but)) {
return but;
}
- but = but->next;
}
return NULL;
}
diff --git a/source/blender/editors/interface/interface_region_color_picker.c b/source/blender/editors/interface/interface_region_color_picker.c
index 0d1b483716e..8bc0f18886b 100644
--- a/source/blender/editors/interface/interface_region_color_picker.c
+++ b/source/blender/editors/interface/interface_region_color_picker.c
@@ -183,7 +183,6 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but,
ColorPicker *cpicker,
const float rgb[3])
{
- uiBut *bt;
float *hsv = cpicker->color_data;
/* Convert from RGB to HSV in perceptually linear space. */
@@ -196,7 +195,7 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but,
/* this updates button strings,
* is hackish... but button pointers are on stack of caller function */
- for (bt = block->buttons.first; bt; bt = bt->next) {
+ LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
if (bt->custom_data != cpicker) {
continue;
}
@@ -849,9 +848,7 @@ static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C),
}
if (add != 0.0f) {
- uiBut *but;
-
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
if (but->type == UI_BTYPE_HSVCUBE && but->active == NULL) {
uiPopupBlockHandle *popup = block->handle;
float rgb[3];
diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c
index 077e8888d53..881ba58174b 100644
--- a/source/blender/editors/interface/interface_region_menu_popup.c
+++ b/source/blender/editors/interface/interface_region_menu_popup.c
@@ -130,9 +130,10 @@ static uiBut *ui_popup_menu_memory__internal(uiBlock *block, uiBut *but)
}
/* get */
- for (but = block->buttons.first; but; but = but->next) {
- if (mem[hash_mod] == ui_popup_string_hash(but->str, but->flag & UI_BUT_HAS_SEP_CHAR)) {
- return but;
+ LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) {
+ if (mem[hash_mod] ==
+ ui_popup_string_hash(but_iter->str, but_iter->flag & UI_BUT_HAS_SEP_CHAR)) {
+ return but_iter;
}
}
@@ -232,7 +233,6 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT);
if (pup->popup) {
- uiBut *bt;
int offset[2];
uiBut *but_activate = NULL;
@@ -241,6 +241,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
UI_block_direction_set(block, direction);
/* offset the mouse position, possibly based on earlier selection */
+ uiBut *bt;
if ((block->flag & UI_BLOCK_POPUP_MEMORY) && (bt = ui_popup_menu_memory_get(block))) {
/* position mouse on last clicked item, at 0.8*width of the
* button, so it doesn't overlap the text too much, also note
@@ -257,15 +258,16 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
/* position mouse at 0.8*width of the button and below the tile
* on the first item */
offset[0] = 0;
- for (bt = block->buttons.first; bt; bt = bt->next) {
- offset[0] = min_ii(offset[0], -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect)));
+ LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) {
+ offset[0] = min_ii(offset[0],
+ -(but_iter->rect.xmin + 0.8f * BLI_rctf_size_x(&but_iter->rect)));
}
offset[1] = 2.1 * UI_UNIT_Y;
- for (bt = block->buttons.first; bt; bt = bt->next) {
- if (ui_but_is_editable(bt)) {
- but_activate = bt;
+ LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) {
+ if (ui_but_is_editable(but_iter)) {
+ but_activate = but_iter;
break;
}
}
@@ -284,17 +286,10 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
else {
/* for a header menu we set the direction automatic */
if (!pup->slideout && flip) {
- ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
- if (area && region) {
- if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
- if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_header_alignment(area)) == RGN_ALIGN_BOTTOM) {
- UI_block_direction_set(block, UI_DIR_UP);
- UI_block_order_flip(block);
- }
- }
- if (region->regiontype == RGN_TYPE_FOOTER) {
- if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_footer_alignment(area)) == RGN_ALIGN_BOTTOM) {
+ if (region) {
+ if (RGN_TYPE_IS_HEADER_ANY(region->regiontype)) {
+ if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_BOTTOM) {
UI_block_direction_set(block, UI_DIR_UP);
UI_block_order_flip(block);
}
@@ -506,8 +501,6 @@ uiLayout *UI_popup_menu_layout(uiPopupMenu *pup)
void UI_popup_menu_reports(bContext *C, ReportList *reports)
{
- Report *report;
-
uiPopupMenu *pup = NULL;
uiLayout *layout;
@@ -515,7 +508,7 @@ void UI_popup_menu_reports(bContext *C, ReportList *reports)
return;
}
- for (report = reports->list.first; report; report = report->next) {
+ LISTBASE_FOREACH (Report *, report, &reports->list) {
int icon;
const char *msg, *msg_next;
diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c
index 0ad7e570e80..43233205877 100644
--- a/source/blender/editors/interface/interface_region_popover.c
+++ b/source/blender/editors/interface/interface_region_popover.c
@@ -171,7 +171,6 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
}
if (!slideout) {
- ScrArea *area = CTX_wm_area(C);
ARegion *region = CTX_wm_region(C);
if (region && region->panels.first) {
@@ -180,14 +179,9 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
}
/* Prefer popover from header to be positioned into the editor. */
- else if (area && region) {
- if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
- if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_header_alignment(area)) == RGN_ALIGN_BOTTOM) {
- UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
- }
- }
- if (region->regiontype == RGN_TYPE_FOOTER) {
- if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_footer_alignment(area)) == RGN_ALIGN_BOTTOM) {
+ else if (region) {
+ if (RGN_TYPE_IS_HEADER_ANY(region->regiontype)) {
+ if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_BOTTOM) {
UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X);
}
}
@@ -209,11 +203,12 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v
if (!handle->refresh) {
uiBut *but = NULL;
uiBut *but_first = NULL;
- for (but = block->buttons.first; but; but = but->next) {
- if ((but_first == NULL) && ui_but_is_editable(but)) {
- but_first = but;
+ LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) {
+ if ((but_first == NULL) && ui_but_is_editable(but_iter)) {
+ but_first = but_iter;
}
- if (but->flag & (UI_SELECT | UI_SELECT_DRAW)) {
+ if (but_iter->flag & (UI_SELECT | UI_SELECT_DRAW)) {
+ but = but_iter;
break;
}
}
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index 13c85952f52..947bdca4f9e 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -59,8 +59,6 @@
*/
void ui_popup_translate(ARegion *region, const int mdiff[2])
{
- uiBlock *block;
-
BLI_rcti_translate(&region->winrct, UNPACK2(mdiff));
ED_region_update_rect(region);
@@ -68,13 +66,12 @@ void ui_popup_translate(ARegion *region, const int mdiff[2])
ED_region_tag_redraw(region);
/* update blocks */
- for (block = region->uiblocks.first; block; block = block->next) {
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
uiPopupBlockHandle *handle = block->handle;
/* Make empty, will be initialized on next use, see T60608. */
BLI_rctf_init(&handle->prev_block_rect, 0, 0, 0, 0);
- uiSafetyRct *saferct;
- for (saferct = block->saferct.first; saferct; saferct = saferct->next) {
+ LISTBASE_FOREACH (uiSafetyRct *, saferct, &block->saferct) {
BLI_rctf_translate(&saferct->parent, UNPACK2(mdiff));
BLI_rctf_translate(&saferct->safety, UNPACK2(mdiff));
}
@@ -373,16 +370,13 @@ static void ui_block_region_refresh(const bContext *C, ARegion *region)
{
ScrArea *ctx_area = CTX_wm_area(C);
ARegion *ctx_region = CTX_wm_region(C);
- uiBlock *block;
if (region->do_draw & RGN_REFRESH_UI) {
ScrArea *handle_ctx_area;
ARegion *handle_ctx_region;
- uiBlock *block_next;
region->do_draw &= ~RGN_REFRESH_UI;
- for (block = region->uiblocks.first; block; block = block_next) {
- block_next = block->next;
+ LISTBASE_FOREACH_MUTABLE (uiBlock *, block, &region->uiblocks) {
uiPopupBlockHandle *handle = block->handle;
if (handle->can_refresh) {
@@ -409,9 +403,7 @@ static void ui_block_region_refresh(const bContext *C, ARegion *region)
static void ui_block_region_draw(const bContext *C, ARegion *region)
{
- uiBlock *block;
-
- for (block = region->uiblocks.first; block; block = block->next) {
+ LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
UI_block_draw(C, block);
}
}
@@ -441,7 +433,6 @@ static void ui_block_region_popup_window_listener(wmWindow *UNUSED(win),
static void ui_popup_block_clip(wmWindow *window, uiBlock *block)
{
- uiBut *bt;
const float xmin_orig = block->rect.xmin;
const int margin = UI_SCREEN_MARGIN;
int winx, winy;
@@ -475,7 +466,7 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block)
/* ensure menu items draw inside left/right boundary */
const float xofs = block->rect.xmin - xmin_orig;
- for (bt = block->buttons.first; bt; bt = bt->next) {
+ LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
bt->rect.xmin += xofs;
bt->rect.xmax += xofs;
}
@@ -483,11 +474,9 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block)
void ui_popup_block_scrolltest(uiBlock *block)
{
- uiBut *bt;
-
block->flag &= ~(UI_BLOCK_CLIPBOTTOM | UI_BLOCK_CLIPTOP);
- for (bt = block->buttons.first; bt; bt = bt->next) {
+ LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
bt->flag &= ~UI_SCROLLED;
}
@@ -496,7 +485,7 @@ void ui_popup_block_scrolltest(uiBlock *block)
}
/* mark buttons that are outside boundary */
- for (bt = block->buttons.first; bt; bt = bt->next) {
+ LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
if (bt->rect.ymin < block->rect.ymin) {
bt->flag |= UI_SCROLLED;
block->flag |= UI_BLOCK_CLIPBOTTOM;
@@ -508,7 +497,7 @@ void ui_popup_block_scrolltest(uiBlock *block)
}
/* mark buttons overlapping arrows, if we have them */
- for (bt = block->buttons.first; bt; bt = bt->next) {
+ LISTBASE_FOREACH (uiBut *, bt, &block->buttons) {
if (block->flag & UI_BLOCK_CLIPBOTTOM) {
if (bt->rect.ymin < block->rect.ymin + UI_MENU_SCROLL_ARROW) {
bt->flag |= UI_SCROLLED;
@@ -535,9 +524,10 @@ static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle)
/* There may actually be a different window active than the one showing the popup, so lookup real
* one. */
if (BLI_findindex(&screen->regionbase, handle->region) == -1) {
- for (win = wm->windows.first; win; win = win->next) {
- screen = WM_window_get_active_screen(win);
+ LISTBASE_FOREACH (wmWindow *, win_iter, &wm->windows) {
+ screen = WM_window_get_active_screen(win_iter);
if (BLI_findindex(&screen->regionbase, handle->region) != -1) {
+ win = win_iter;
break;
}
}
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index 2010d89165e..adb2c1c802f 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -592,15 +592,15 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
/* indicate more */
if (data->items.more) {
ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_icon_draw(rect.xmax - 18, rect.ymin - 7, ICON_TRIA_DOWN);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
if (data->items.offset) {
ui_searchbox_butrect(&rect, data, 0);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_icon_draw(rect.xmin, rect.ymax - 9, ICON_TRIA_UP);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
else {
@@ -657,15 +657,15 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region)
/* indicate more */
if (data->items.more) {
ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
if (data->items.offset) {
ui_searchbox_butrect(&rect, data, 0);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
}
@@ -953,15 +953,15 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
/* indicate more */
if (data->items.more) {
ui_searchbox_butrect(&rect, data, data->items.maxitem - 1);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
if (data->items.offset) {
ui_searchbox_butrect(&rect, data, 0);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
}
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 41b41cb3d75..c324e27dff9 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -63,7 +63,7 @@
#include "BLT_translation.h"
#ifdef WITH_PYTHON
-# include "BPY_extern.h"
+# include "BPY_extern_run.h"
#endif
#include "ED_screen.h"
@@ -433,7 +433,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
expr_result = BLI_strdup(has_valid_context_error);
}
- else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
+ else if (BPY_run_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
if (STREQ(expr_result, "")) {
MEM_freeN(expr_result);
expr_result = NULL;
@@ -490,7 +490,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
expr_result = BLI_strdup(has_valid_context_error);
}
- else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
+ else if (BPY_run_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
if (STREQ(expr_result, ".")) {
MEM_freeN(expr_result);
expr_result = NULL;
@@ -594,7 +594,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
shortcut = BLI_strdup(has_valid_context_error);
}
- else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
+ else if (BPY_run_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
if (expr_result != 0) {
wmKeyMap *keymap = (wmKeyMap *)expr_result;
LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
@@ -658,7 +658,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
/* pass */
}
- else if (BPY_execute_string_as_string_and_size(
+ else if (BPY_run_string_as_string_and_size(
C, expr_imports, expr, __func__, &expr_result, &expr_result_len)) {
/* pass. */
}
@@ -736,7 +736,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
/* pass */
}
- else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
+ else if (BPY_run_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
if (expr_result != 0) {
{
uiTooltipField *field = text_field_add(data,
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index 5310ff0e3ec..28279996559 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -426,7 +426,6 @@ int UI_fontstyle_height_max(const uiFontStyle *fs)
/* reading without uifont will create one */
void uiStyleInit(void)
{
- uiFont *font;
uiStyle *style = U.uistyles.first;
/* recover from uninitialized dpi */
@@ -435,7 +434,7 @@ void uiStyleInit(void)
}
CLAMP(U.dpi, 48, 144);
- for (font = U.uifonts.first; font; font = font->next) {
+ LISTBASE_FOREACH (uiFont *, font, &U.uifonts) {
BLF_unload_id(font->blf_id);
}
@@ -449,24 +448,24 @@ void uiStyleInit(void)
blf_mono_font_render = -1;
}
- font = U.uifonts.first;
+ uiFont *font_first = U.uifonts.first;
/* default builtin */
- if (font == NULL) {
- font = MEM_callocN(sizeof(uiFont), "ui font");
- BLI_addtail(&U.uifonts, font);
+ if (font_first == NULL) {
+ font_first = MEM_callocN(sizeof(uiFont), "ui font");
+ BLI_addtail(&U.uifonts, font_first);
}
if (U.font_path_ui[0]) {
- BLI_strncpy(font->filename, U.font_path_ui, sizeof(font->filename));
- font->uifont_id = UIFONT_CUSTOM1;
+ BLI_strncpy(font_first->filename, U.font_path_ui, sizeof(font_first->filename));
+ font_first->uifont_id = UIFONT_CUSTOM1;
}
else {
- BLI_strncpy(font->filename, "default", sizeof(font->filename));
- font->uifont_id = UIFONT_DEFAULT;
+ BLI_strncpy(font_first->filename, "default", sizeof(font_first->filename));
+ font_first->uifont_id = UIFONT_DEFAULT;
}
- for (font = U.uifonts.first; font; font = font->next) {
+ LISTBASE_FOREACH (uiFont *, font, &U.uifonts) {
const bool unique = false;
if (font->uifont_id == UIFONT_DEFAULT) {
@@ -535,7 +534,7 @@ void uiStyleInit(void)
flag_enable |= BLF_MONOCHROME;
}
- for (font = U.uifonts.first; font; font = font->next) {
+ LISTBASE_FOREACH (uiFont *, font, &U.uifonts) {
if (font->blf_id != -1) {
BLF_disable(font->blf_id, flag_disable);
BLF_enable(font->blf_id, flag_enable);
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index cdfe6120eee..0e801c8cee2 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -395,11 +395,10 @@ static void id_search_cb(const bContext *C,
{
TemplateID *template_ui = (TemplateID *)arg_template;
ListBase *lb = template_ui->idlb;
- ID *id;
int flag = RNA_property_flag(template_ui->prop);
/* ID listbase */
- for (id = lb->first; id; id = id->next) {
+ LISTBASE_FOREACH (ID *, id, lb) {
if (!id_search_add(C, template_ui, flag, str, items, id)) {
break;
}
@@ -416,11 +415,10 @@ static void id_search_cb_tagged(const bContext *C,
{
TemplateID *template_ui = (TemplateID *)arg_template;
ListBase *lb = template_ui->idlb;
- ID *id;
int flag = RNA_property_flag(template_ui->prop);
/* ID listbase */
- for (id = lb->first; id; id = id->next) {
+ LISTBASE_FOREACH (ID *, id, lb) {
if (id->tag & LIB_TAG_DOIT) {
if (!id_search_add(C, template_ui, flag, str, items, id)) {
break;
@@ -2420,9 +2418,8 @@ static eAutoPropButsReturn template_operator_property_buts_draw_single(
/* Only do this if we're not refreshing an existing UI. */
if (block->oldblock == NULL) {
const bool is_popup = (block->flag & UI_BLOCK_KEEP_OPEN) != 0;
- uiBut *but;
- for (but = block->buttons.first; but; but = but->next) {
+ LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
/* no undo for buttons for operator redo panels */
UI_but_flag_disable(but, UI_BUT_UNDO);
@@ -5415,7 +5412,6 @@ void uiTemplatePalette(uiLayout *layout,
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
PointerRNA cptr;
Palette *palette;
- PaletteColor *color;
uiBlock *block;
uiLayout *col;
uiBut *but = NULL;
@@ -5437,8 +5433,6 @@ void uiTemplatePalette(uiLayout *layout,
palette = cptr.data;
- color = palette->colors.first;
-
col = uiLayoutColumn(layout, true);
uiLayoutRow(col, true);
uiDefIconButO(block,
@@ -5461,7 +5455,7 @@ void uiTemplatePalette(uiLayout *layout,
UI_UNIT_X,
UI_UNIT_Y,
NULL);
- if (color) {
+ if (palette->colors.first != NULL) {
but = uiDefIconButO(block,
UI_BTYPE_BUT,
"PALETTE_OT_color_move",
@@ -5496,7 +5490,7 @@ void uiTemplatePalette(uiLayout *layout,
col = uiLayoutColumn(layout, true);
uiLayoutRow(col, true);
- for (; color; color = color->next) {
+ LISTBASE_FOREACH (PaletteColor *, color, &palette->colors) {
PointerRNA color_ptr;
if (row_cols >= cols_per_row) {
@@ -6650,9 +6644,8 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
UI_block_func_handle_set(block, do_running_jobs, NULL);
- Scene *scene;
/* another scene can be rendering too, for example via compositor */
- for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) {
handle_event = B_STOPOTHER;
icon = ICON_NONE;
@@ -7366,10 +7359,12 @@ void uiTemplateCacheFile(uiLayout *layout,
int uiTemplateRecentFiles(uiLayout *layout, int rows)
{
- const RecentFile *recent;
int i;
+ LISTBASE_FOREACH_INDEX (RecentFile *, recent, &G.recent_files, i) {
+ if (i >= rows) {
+ break;
+ }
- for (recent = G.recent_files.first, i = 0; (i < rows) && (recent); recent = recent->next, i++) {
const char *filename = BLI_path_basename(recent->filepath);
PointerRNA ptr;
uiItemFullO(layout,
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 4a1c7be918e..f44987ac1d2 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -714,12 +714,8 @@ bool UI_butstore_is_valid(uiButStore *bs)
bool UI_butstore_is_registered(uiBlock *block, uiBut *but)
{
- uiButStore *bs_handle;
-
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
- uiButStoreElem *bs_elem;
-
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) {
+ LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) {
if (*bs_elem->but_p == but) {
return true;
}
@@ -740,10 +736,7 @@ void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p)
void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p)
{
- uiButStoreElem *bs_elem, *bs_elem_next;
-
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem_next) {
- bs_elem_next = bs_elem->next;
+ LISTBASE_FOREACH_MUTABLE (uiButStoreElem *, bs_elem, &bs_handle->items) {
if (bs_elem->but_p == but_p) {
BLI_remlink(&bs_handle->items, bs_elem);
MEM_freeN(bs_elem);
@@ -758,12 +751,10 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p)
*/
bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src)
{
- uiButStore *bs_handle;
bool found = false;
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
- uiButStoreElem *bs_elem;
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) {
+ LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) {
if (*bs_elem->but_p == but_src) {
*bs_elem->but_p = but_dst;
found = true;
@@ -779,14 +770,9 @@ bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *bu
*/
void UI_butstore_clear(uiBlock *block)
{
- uiButStore *bs_handle;
-
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
- uiButStoreElem *bs_elem;
-
+ LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) {
bs_handle->block = NULL;
-
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) {
*bs_elem->but_p = NULL;
}
}
@@ -797,8 +783,6 @@ void UI_butstore_clear(uiBlock *block)
*/
void UI_butstore_update(uiBlock *block)
{
- uiButStore *bs_handle;
-
/* move this list to the new block */
if (block->oldblock) {
if (block->oldblock->butstore.first) {
@@ -812,17 +796,14 @@ void UI_butstore_update(uiBlock *block)
/* warning, loop-in-loop, in practice we only store <10 buttons at a time,
* so this isn't going to be a problem, if that changes old-new mapping can be cached first */
- for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) {
-
+ LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) {
BLI_assert((bs_handle->block == NULL) || (bs_handle->block == block) ||
(block->oldblock && block->oldblock == bs_handle->block));
if (bs_handle->block == block->oldblock) {
- uiButStoreElem *bs_elem;
-
bs_handle->block = block;
- for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) {
+ LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) {
if (*bs_elem->but_p) {
uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 1be62e535de..c1801290152 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -29,6 +29,7 @@
#include "DNA_brush_types.h"
#include "DNA_userdef_types.h"
+#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_rect.h"
#include "BLI_string.h"
@@ -525,7 +526,7 @@ void UI_draw_anti_tria(
/* Note: This won't give back the original color. */
draw_color[3] *= 1.0f / WIDGET_AA_JITTER;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -544,7 +545,7 @@ void UI_draw_anti_tria(
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* triangle 'icon' inside rect */
@@ -569,7 +570,7 @@ void UI_draw_anti_fan(float tri_array[][2], uint length, const float color[4])
copy_v4_v4(draw_color, color);
draw_color[3] *= 2.0f / WIDGET_AA_JITTER;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -593,7 +594,7 @@ void UI_draw_anti_fan(float tri_array[][2], uint length, const float color[4])
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void widget_init(uiWidgetBase *wtb)
@@ -1170,7 +1171,7 @@ void UI_widgetbase_draw_cache_flush(void)
/* draw single */
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
GPU_batch_uniform_4fv_array(
- batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)g_widget_base_batch.params);
+ batch, "parameters", MAX_WIDGET_PARAMETERS, (float(*)[4])g_widget_base_batch.params);
GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
GPU_batch_draw(batch);
}
@@ -1179,7 +1180,7 @@ void UI_widgetbase_draw_cache_flush(void)
GPU_batch_uniform_4fv_array(batch,
"parameters",
MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH,
- (float *)g_widget_base_batch.params);
+ (float(*)[4])g_widget_base_batch.params);
GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
GPU_batch_draw_instanced(batch, g_widget_base_batch.count);
}
@@ -1197,11 +1198,11 @@ void UI_widgetbase_draw_cache_end(void)
BLI_assert(g_widget_base_batch.enabled == true);
g_widget_base_batch.enabled = false;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* Disable cached/instanced drawing and enforce single widget drawing pipeline.
@@ -1247,7 +1248,7 @@ static void draw_widgetbase_batch(uiWidgetBase *wtb)
GPUBatch *batch = ui_batch_roundbox_widget_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE);
GPU_batch_uniform_4fv_array(
- batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)&wtb->uniform_params);
+ batch, "parameters", MAX_WIDGET_PARAMETERS, (float(*)[4]) & wtb->uniform_params);
GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
GPU_batch_draw(batch);
}
@@ -1307,9 +1308,9 @@ static void widgetbase_draw_ex(uiWidgetBase *wtb,
widgetbase_set_uniform_colors_ubv(
wtb, inner_col1, inner_col2, outline_col, emboss_col, tria_col, show_alpha_checkers);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
draw_widgetbase_batch(wtb);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
@@ -1363,9 +1364,9 @@ static void widget_draw_icon(
float aspect, height;
if (but->flag & UI_BUT_ICON_PREVIEW) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
widget_draw_preview(icon, alpha, rect);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
return;
}
@@ -1401,7 +1402,7 @@ static void widget_draw_icon(
}
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
if (icon && icon != ICON_BLANK1) {
float ofs = 1.0f / aspect;
@@ -1454,7 +1455,7 @@ static void widget_draw_icon(
}
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void widget_draw_submenu_tria(const uiBut *but,
@@ -1475,9 +1476,9 @@ static void widget_draw_submenu_tria(const uiBut *but,
BLI_rctf_init(&tria_rect, xs, xs + tria_width, ys, ys + tria_height);
BLI_rctf_scale(&tria_rect, 0.4f);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
ui_draw_anti_tria_rect(&tria_rect, 'h', col);
}
@@ -2022,9 +2023,9 @@ static void widget_draw_text(const uiFontStyle *fstyle,
if (drawstr[0] != 0) {
/* We are drawing on top of widget bases. Flush cache. */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
if (but->selsta >= but->ofs) {
selsta_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selsta - but->ofs);
@@ -2069,9 +2070,9 @@ static void widget_draw_text(const uiFontStyle *fstyle,
t = 0;
}
/* We are drawing on top of widget bases. Flush cache. */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
uint pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
@@ -2242,7 +2243,7 @@ static void widget_draw_extra_icons(const uiWidgetColors *wcol,
float alpha)
{
/* inverse order, from right to left. */
- for (uiButExtraOpIcon *op_icon = but->extra_op_icons.last; op_icon; op_icon = op_icon->prev) {
+ LISTBASE_FOREACH_BACKWARD (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) {
rcti temp = *rect;
temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f);
@@ -2266,9 +2267,9 @@ static void widget_draw_node_link_socket(const uiWidgetColors *wcol,
rgba_uchar_to_float(col, but->col);
col[3] *= alpha;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
ED_node_socket_draw(but->custom_data, rect, col, scale);
}
@@ -2327,9 +2328,9 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
/* draw icon in rect above the space reserved for the label */
rect->ymin += text_size;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
widget_draw_preview(icon, alpha, rect);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* offset rect to draw label in */
rect->ymin -= text_size;
@@ -2784,16 +2785,14 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir
rect->ymax += 0.1f * U.widget_unit;
}
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
widget_softshadow(rect, roundboxalign, wcol->roundness * U.widget_unit);
round_box_edges(&wtb, roundboxalign, rect, wcol->roundness * U.widget_unit);
wtb.draw_emboss = false;
widgetbase_draw(&wtb, wcol);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void ui_hsv_cursor(float x, float y)
@@ -2805,11 +2804,11 @@ static void ui_hsv_cursor(float x, float y)
immUniformColor3f(1.0f, 1.0f, 1.0f);
imm_draw_circle_fill_2d(pos, x, y, 3.0f * U.pixelsize, 8);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
immUniformColor3f(0.0f, 0.0f, 0.0f);
imm_draw_circle_wire_2d(pos, x, y, 3.0f * U.pixelsize, 12);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
immUnbindProgram();
@@ -2937,7 +2936,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
immUniformColor3ubv(wcol->outline);
@@ -2945,7 +2944,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
/* cursor */
@@ -3244,9 +3243,9 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect)
}));
/* We are drawing on top of widget bases. Flush cache. */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* cursor */
x = rect->xmin + 0.5f * BLI_rcti_size_x(rect);
@@ -3270,7 +3269,7 @@ static void ui_draw_separator(const rcti *rect, const uiWidgetColors *wcol)
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformColor4ubv(col);
GPU_line_width(1.0f);
@@ -3279,7 +3278,7 @@ static void ui_draw_separator(const rcti *rect, const uiWidgetColors *wcol)
immVertex2f(pos, rect->xmax, y);
immEnd();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();
}
@@ -3837,9 +3836,9 @@ static void widget_swatch(
bw += (bw < 0.5f) ? 0.5f : -0.5f;
/* We are drawing on top of widget bases. Flush cache. */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -4201,9 +4200,9 @@ static void widget_tab(uiWidgetColors *wcol, rcti *rect, int state, int roundbox
widgetbase_draw(&wtb, wcol);
/* We are drawing on top of widget bases. Flush cache. */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_widgetbase_draw_cache_flush();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
#ifdef USE_TAB_SHADED_HIGHLIGHT
/* draw outline (3d look) */
@@ -4818,12 +4817,12 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
}
if (disabled) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
}
wt->text(fstyle, &wt->wcol, but, rect);
if (disabled) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
}
@@ -4906,7 +4905,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol,
rect->xmax - unit_size) :
BLI_rcti_cent_x(rect);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* Extracted from 'widget_menu_back', keep separate to avoid menu changes breaking popovers */
{
@@ -4930,7 +4929,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol,
const int sign = is_down ? 1 : -1;
float y = is_down ? rect->ymax : rect->ymin;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immBegin(GPU_PRIM_TRIS, 3);
immUniformColor4ub(UNPACK3(wcol->outline), 166);
immVertex2f(pos, cent_x - unit_half, y);
@@ -4940,7 +4939,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol,
y = y - sign * round(U.pixelsize * 1.41);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immBegin(GPU_PRIM_TRIS, 3);
immUniformColor4ub(0, 0, 0, 0);
immVertex2f(pos, cent_x - unit_half, y);
@@ -4948,7 +4947,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol,
immVertex2f(pos, cent_x, y + sign * unit_half);
immEnd();
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immBegin(GPU_PRIM_TRIS, 3);
immUniformColor4ubv(wcol->inner);
immVertex2f(pos, cent_x - unit_half, y);
@@ -4959,7 +4958,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol,
immUnbindProgram();
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
void ui_draw_popover_back(struct ARegion *region,
@@ -5060,7 +5059,7 @@ void ui_draw_pie_center(uiBlock *block)
GPU_matrix_push();
GPU_matrix_translate_2f(cx, cy);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
if (btheme->tui.wcol_pie_menu.shaded) {
uchar col1[4], col2[4];
shadecolors4(col1,
@@ -5143,7 +5142,7 @@ void ui_draw_pie_center(uiBlock *block)
false);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_matrix_pop();
}
@@ -5164,11 +5163,9 @@ static void ui_draw_widget_back_color(uiWidgetTypeEnum type,
uiWidgetType *wt = widget_type(type);
if (use_shadow) {
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
rcti rect_copy = *rect;
@@ -5291,10 +5288,10 @@ void ui_draw_menu_item(const uiFontStyle *fstyle,
height = ICON_SIZE_FROM_BUTRECT(rect);
aspect = ICON_DEFAULT_HEIGHT / height;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* XXX scale weak get from fstyle? */
UI_icon_draw_ex(xs, ys, iconid, aspect, 1.0f, 0.0f, wt->wcol.text, false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* part text right aligned */
@@ -5330,9 +5327,9 @@ void ui_draw_preview_item(
/* draw icon in rect above the space reserved for the label */
rect->ymin += text_size;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
widget_draw_preview(iconid, 1.0f, rect);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
BLF_width_and_height(
fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]);
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index f15a95880f8..d4f81a89bc3 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -870,8 +870,6 @@ void UI_view2d_curRect_changed(const bContext *C, View2D *v2d)
* to make sure 'related' views stay in synchrony */
void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag)
{
- ARegion *region;
-
/* don't continue if no view syncing to be done */
if ((v2dcur->flag & (V2D_VIEWSYNC_SCREEN_TIME | V2D_VIEWSYNC_AREA_VERTICAL)) == 0) {
return;
@@ -879,7 +877,7 @@ void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag)
/* check if doing within area syncing (i.e. channels/vertical) */
if ((v2dcur->flag & V2D_VIEWSYNC_AREA_VERTICAL) && (area)) {
- for (region = area->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
/* don't operate on self */
if (v2dcur != &region->v2d) {
/* only if view has vertical locks enabled */
@@ -905,7 +903,7 @@ void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag)
/* check if doing whole screen syncing (i.e. time/horizontal) */
if ((v2dcur->flag & V2D_VIEWSYNC_SCREEN_TIME) && (screen)) {
LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) {
- for (region = area_iter->regionbase.first; region; region = region->next) {
+ LISTBASE_FOREACH (ARegion *, region, &area_iter->regionbase) {
/* don't operate on self */
if (v2dcur != &region->v2d) {
/* only if view has horizontal locks enabled */
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 7caa61ec91d..eb47c5c3e6d 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -1157,8 +1157,8 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
const bool zoom_to_pos = use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS);
/* get amount to move view by */
- dx = RNA_float_get(op->ptr, "deltax") / U.pixelsize;
- dy = RNA_float_get(op->ptr, "deltay") / U.pixelsize;
+ dx = RNA_float_get(op->ptr, "deltax") / U.dpi_fac;
+ dy = RNA_float_get(op->ptr, "deltay") / U.dpi_fac;
if (U.uiflag & USER_ZOOM_INVERT) {
dx *= -1;
diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index 096dc44c758..45ea52bdebc 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -113,6 +113,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op)
MEM_SAFE_FREE(op->customdata);
const bool selected_objects_only = RNA_boolean_get(op->ptr, "selected_objects_only");
+ const bool visible_objects_only = RNA_boolean_get(op->ptr, "visible_objects_only");
const bool export_animation = RNA_boolean_get(op->ptr, "export_animation");
const bool export_hair = RNA_boolean_get(op->ptr, "export_hair");
const bool export_uvmaps = RNA_boolean_get(op->ptr, "export_uvmaps");
@@ -128,6 +129,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op)
export_normals,
export_materials,
selected_objects_only,
+ visible_objects_only,
use_instancing,
evaluation_mode,
};
@@ -149,6 +151,7 @@ static void wm_usd_export_draw(bContext *UNUSED(C), wmOperator *op)
col = uiLayoutColumn(box, true);
uiItemR(col, ptr, "selected_objects_only", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "visible_objects_only", 0, NULL, ICON_NONE);
col = uiLayoutColumn(box, true);
uiItemR(col, ptr, "export_animation", 0, NULL, ICON_NONE);
@@ -192,6 +195,13 @@ void WM_OT_usd_export(struct wmOperatorType *ot)
"exported as empty transform");
RNA_def_boolean(ot->srna,
+ "visible_objects_only",
+ true,
+ "Visible Only",
+ "Only visible objects are exported. Invisible parents of exported objects are "
+ "exported as empty transform");
+
+ RNA_def_boolean(ot->srna,
"export_animation",
false,
"Animation",
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index c617c921d70..dbaa335a9bf 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -594,9 +594,7 @@ static void draw_mask_layers(const bContext *C,
const int width,
const int height)
{
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_program_point_size(true);
MaskLayer *mask_layer;
@@ -633,7 +631,7 @@ static void draw_mask_layers(const bContext *C,
}
GPU_program_point_size(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
void ED_mask_draw(const bContext *C, const char draw_flag, const char draw_type)
@@ -740,8 +738,7 @@ void ED_mask_draw_region(
if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
/* More blending types could be supported in the future. */
- GPU_blend(true);
- GPU_blend_set_func(GPU_DST_COLOR, GPU_ZERO);
+ GPU_blend(GPU_BLEND_MULTIPLY);
}
GPU_matrix_push();
@@ -758,7 +755,7 @@ void ED_mask_draw_region(
GPU_matrix_pop();
if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
MEM_freeN(buffer);
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index b02e48a652e..94cd7650abe 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1128,9 +1128,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
int i, snapped_verts_count, other_verts_count;
float fcol[4];
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertBuf *vert = GPU_vertbuf_create_with_format(format);
GPU_vertbuf_data_alloc(vert, kcd->totlinehit);
@@ -1166,7 +1164,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v
GPU_batch_discard(batch);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
if (kcd->totkedge > 0) {
diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c
index 8eeba5007e1..34fcee779de 100644
--- a/source/blender/editors/mesh/editmesh_mask_extract.c
+++ b/source/blender/editors/mesh/editmesh_mask_extract.c
@@ -354,10 +354,6 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
if (ob->mode == OB_MODE_SCULPT) {
ED_sculpt_undo_geometry_begin(ob, "mask slice");
- /* TODO: The ideal functionality would be to preserve the current face sets and add a new one
- * for the new triangles, but this data-layer needs to be rebuild in order to make sculpt mode
- * not crash when modifying the geometry. */
- CustomData_free_layers(&mesh->pdata, CD_SCULPT_FACE_SETS, mesh->totpoly);
}
BMesh *bm;
@@ -429,14 +425,14 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
BKE_mesh_calc_normals(ob->data);
if (ob->mode == OB_MODE_SCULPT) {
- ED_sculpt_undo_geometry_end(ob);
SculptSession *ss = ob->sculpt;
- /* Rebuild a new valid Face Set layer for the object. */
- ss->face_sets = CustomData_add_layer(
- &mesh->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, mesh->totpoly);
- for (int i = 0; i < mesh->totpoly; i++) {
- ss->face_sets[i] = 1;
+ ss->face_sets = CustomData_get_layer(&((Mesh *)ob->data)->pdata, CD_SCULPT_FACE_SETS);
+ if (ss->face_sets) {
+ /* Assign a new Face Set ID to the new faces created by the slice operation. */
+ const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(ob->data);
+ ED_sculpt_face_sets_initialize_none_to_id(ob->data, next_face_set_id);
}
+ ED_sculpt_undo_geometry_end(ob);
}
BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index eb8b976320f..4d55aff1d1f 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -745,7 +745,7 @@ static int bake(Render *re,
/* We build a depsgraph for the baking,
* so we don't need to change the original data to adjust visibility and modifiers. */
Depsgraph *depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
- DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer);
+ DEG_graph_build_from_view_layer(depsgraph);
int op_result = OPERATOR_CANCELLED;
bool ok = false;
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index bcb1b8afbdd..70404af6433 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -663,10 +663,13 @@ static const EnumPropertyItem constraint_owner_items[] = {
{0, NULL, 0, NULL, NULL},
};
-static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type)
+static bool edit_constraint_poll_generic(bContext *C,
+ StructRNA *rna_type,
+ const bool is_liboverride_allowed)
{
PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", rna_type);
Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C);
+ bConstraint *con = ptr.data;
if (!ob) {
CTX_wm_operator_poll_msg_set(C, "Context missing active object");
@@ -678,9 +681,11 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type)
return false;
}
- if (ID_IS_OVERRIDE_LIBRARY(ob) && ptr.data != NULL) {
- CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override");
- return (((bConstraint *)ptr.data)->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) != 0;
+ if (ID_IS_OVERRIDE_LIBRARY(ob) && !is_liboverride_allowed) {
+ if ((con == NULL) || (con->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) != 0) {
+ CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override");
+ return false;
+ }
}
return true;
@@ -688,7 +693,14 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type)
static bool edit_constraint_poll(bContext *C)
{
- return edit_constraint_poll_generic(C, &RNA_Constraint);
+ return edit_constraint_poll_generic(C, &RNA_Constraint, false);
+}
+
+/* Used by operators performing actions allowed also on constraints from the overridden linked
+ * object (not only from added 'local' ones). */
+static bool edit_constraint_liboverride_allowed_poll(bContext *C)
+{
+ return edit_constraint_poll_generic(C, &RNA_Constraint, true);
}
static void edit_constraint_properties(wmOperatorType *ot)
@@ -864,7 +876,7 @@ void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot)
/* callbacks */
ot->invoke = stretchto_reset_invoke;
ot->exec = stretchto_reset_exec;
- ot->poll = edit_constraint_poll;
+ ot->poll = edit_constraint_liboverride_allowed_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -919,7 +931,7 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot)
/* callbacks */
ot->invoke = limitdistance_reset_invoke;
ot->exec = limitdistance_reset_exec;
- ot->poll = edit_constraint_poll;
+ ot->poll = edit_constraint_liboverride_allowed_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -997,7 +1009,7 @@ void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot)
/* callbacks */
ot->invoke = childof_set_inverse_invoke;
ot->exec = childof_set_inverse_exec;
- ot->poll = edit_constraint_poll;
+ ot->poll = edit_constraint_liboverride_allowed_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1046,7 +1058,7 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot)
/* callbacks */
ot->invoke = childof_clear_inverse_invoke;
ot->exec = childof_clear_inverse_exec;
- ot->poll = edit_constraint_poll;
+ ot->poll = edit_constraint_liboverride_allowed_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1693,8 +1705,8 @@ void POSE_OT_constraints_clear(wmOperatorType *ot)
/* callbacks */
ot->exec = pose_constraints_clear_exec;
- ot->poll =
- ED_operator_posemode_exclusive; // XXX - do we want to ensure there are selected bones too?
+ ot->poll = ED_operator_posemode_exclusive; // XXX - do we want to ensure there are selected
+ // bones too?
}
static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
@@ -1942,7 +1954,8 @@ static bool get_new_constraint_target(
/* perform some special operations on the target */
if (only_curve) {
- /* Curve-Path option must be enabled for follow-path constraints to be able to work */
+ /* Curve-Path option must be enabled for follow-path constraints to be able to work
+ */
Curve *cu = (Curve *)ob->data;
cu->flag |= CU_PATH;
}
@@ -2214,8 +2227,8 @@ void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot)
/* identifiers */
ot->name = "Add Constraint (with Targets)";
ot->description =
- "Add a constraint to the active object, with target (where applicable) set to the selected "
- "Objects/Bones";
+ "Add a constraint to the active object, with target (where applicable) set to the "
+ "selected Objects/Bones";
ot->idname = "OBJECT_OT_constraint_add_with_targets";
/* api callbacks */
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index ceb6553bdf6..14882ab8ffc 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -107,7 +107,7 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
BKE_object_eval_reset(ob_eval);
if (ob->type == OB_MESH) {
- Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
+ Mesh *me_eval = mesh_create_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
BKE_mesh_eval_delete(me_eval);
}
else if (ob->type == OB_LATTICE) {
diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
index d5715cf6879..9be84dc4b8c 100644
--- a/source/blender/editors/object/object_remesh.c
+++ b/source/blender/editors/object/object_remesh.c
@@ -294,7 +294,7 @@ static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar),
{
VoxelSizeEditCustomData *cd = arg;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
uint pos3d = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@@ -363,7 +363,7 @@ static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar),
GPU_matrix_pop();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 488bb7121a2..eb7ddfefb9c 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -3213,11 +3213,11 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)
immUniformColor4ub(255, 255, 255, 128);
GPU_line_smooth(true);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
imm_draw_circle_wire_2d(pos, (float)x, (float)y, pe_brush_size_get(scene, brush), 40);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
immUnbindProgram();
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index f75dd428968..52a7b92217b 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -879,7 +879,6 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = oglrender->scene;
int i;
@@ -929,7 +928,7 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
if (oglrender->timer) { /* exec will not have a timer */
Depsgraph *depsgraph = oglrender->depsgraph;
scene->r.cfra = oglrender->cfrao;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer);
}
@@ -1119,7 +1118,6 @@ static bool schedule_write_result(OGLRender *oglrender, RenderResult *rr)
static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
OGLRender *oglrender = op->customdata;
Scene *scene = oglrender->scene;
Depsgraph *depsgraph = oglrender->depsgraph;
@@ -1134,7 +1132,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
CFRA++;
}
while (CFRA < oglrender->nfra) {
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
CFRA++;
}
@@ -1161,7 +1159,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
WM_cursor_time(oglrender->win, scene->r.cfra);
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
if (view_context) {
if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera &&
diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c
index fa63a890de7..d599c1cbcf0 100644
--- a/source/blender/editors/scene/scene_edit.c
+++ b/source/blender/editors/scene/scene_edit.c
@@ -119,7 +119,7 @@ void ED_scene_change_update(Main *bmain, Scene *scene, ViewLayer *layer)
Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, layer, true);
BKE_scene_set_background(bmain, scene);
- DEG_graph_relations_update(depsgraph, bmain, scene, layer);
+ DEG_graph_relations_update(depsgraph);
DEG_on_visible_update(bmain, false);
ED_render_engine_changed(bmain, false);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 38bac3afef6..5004b0132c2 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -93,9 +93,7 @@ static void region_draw_emboss(const ARegion *region, const rcti *scirct, int si
rect.ymax = scirct->ymax - region->winrct.ymin;
/* set transp line */
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
float color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
UI_GetThemeColor3fv(TH_EDITOR_OUTLINE, color);
@@ -134,8 +132,7 @@ static void region_draw_emboss(const ARegion *region, const rcti *scirct, int si
immEnd();
immUnbindProgram();
- GPU_blend(false);
- GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_NONE);
}
void ED_region_pixelspace(ARegion *region)
@@ -248,7 +245,7 @@ static void draw_azone_arrow(float x1, float y1, float x2, float y2, AZEdge edge
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* NOTE(fclem): There is something strange going on with Mesa and GPU_SHADER_2D_UNIFORM_COLOR
* that causes a crash on some GPUs (see T76113). Using 3D variant avoid the issue. */
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -266,12 +263,12 @@ static void draw_azone_arrow(float x1, float y1, float x2, float y2, AZEdge edge
immEnd();
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void region_draw_azone_tab_arrow(ScrArea *area, ARegion *region, AZone *az)
{
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* add code to draw region hidden as 'too small' */
switch (az->edge) {
@@ -312,9 +309,7 @@ static void region_draw_azones(ScrArea *area, ARegion *region)
}
GPU_line_width(1.0f);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_matrix_push();
GPU_matrix_translate_2f(-region->winrct.xmin, -region->winrct.ymin);
@@ -349,7 +344,7 @@ static void region_draw_azones(ScrArea *area, ARegion *region)
GPU_matrix_pop();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void region_draw_status_text(ScrArea *area, ARegion *region)
@@ -378,8 +373,7 @@ static void region_draw_status_text(ScrArea *area, ARegion *region)
const float y1 = pad;
const float y2 = region->winy - pad;
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
UI_GetThemeColor3fv(TH_BACK, color);
@@ -548,7 +542,7 @@ void ED_region_do_draw(bContext *C, ARegion *region)
/* for debugging unneeded area redraws and partial redraw */
if (G.debug_value == 888) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -559,7 +553,7 @@ void ED_region_do_draw(bContext *C, ARegion *region)
region->drawrct.xmax - region->winrct.xmin,
region->drawrct.ymax - region->winrct.ymin);
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
memset(&region->drawrct, 0, sizeof(region->drawrct));
@@ -2053,6 +2047,241 @@ void ED_area_data_swap(ScrArea *area_dst, ScrArea *area_src)
SWAP(ListBase, area_dst->regionbase, area_src->regionbase);
}
+/* -------------------------------------------------------------------- */
+/** \name Region Alignment Syncing for Space Switching
+ * \{ */
+
+/**
+ * Store the alignment & other info per region type
+ * (use as a region-type aligned array).
+ *
+ * \note Currently this is only done for headers,
+ * we might want to do this with the tool-bar in the future too.
+ */
+struct RegionTypeAlignInfo {
+ struct {
+ /**
+ * Values match #ARegion.alignment without flags (see #RGN_ALIGN_ENUM_FROM_MASK).
+ * store all so we can sync alignment without adding extra checks.
+ */
+ short alignment;
+ /**
+ * Needed for detecting which header displays the space-type switcher.
+ */
+ bool hidden;
+ } by_type[RGN_TYPE_LEN];
+};
+
+static void region_align_info_from_area(ScrArea *area, struct RegionTypeAlignInfo *r_align_info)
+{
+ for (int index = 0; index < RGN_TYPE_LEN; index++) {
+ r_align_info->by_type[index].alignment = -1;
+ /* Default to true, when it doesn't exist - it's effectively hidden. */
+ r_align_info->by_type[index].hidden = true;
+ }
+
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
+ const int index = region->regiontype;
+ if ((uint)index < RGN_TYPE_LEN) {
+ r_align_info->by_type[index].alignment = RGN_ALIGN_ENUM_FROM_MASK(region->alignment);
+ r_align_info->by_type[index].hidden = (region->flag & RGN_FLAG_HIDDEN) != 0;
+ }
+ }
+}
+
+/**
+ * Keeping alignment between headers keep the space-type selector button in the same place.
+ * This is complicated by the editor-type selector being placed on the header
+ * closest to the screen edge which changes based on hidden state.
+ *
+ * The tool-header is used when visible, otherwise the header is used.
+ */
+static short region_alignment_from_header_and_tool_header_state(
+ const struct RegionTypeAlignInfo *region_align_info, const short fallback)
+{
+ const short header_alignment = region_align_info->by_type[RGN_TYPE_HEADER].alignment;
+ const short tool_header_alignment = region_align_info->by_type[RGN_TYPE_TOOL_HEADER].alignment;
+
+ const bool header_hidden = region_align_info->by_type[RGN_TYPE_HEADER].hidden;
+ const bool tool_header_hidden = region_align_info->by_type[RGN_TYPE_TOOL_HEADER].hidden;
+
+ if ((tool_header_alignment != -1) &&
+ /* If tool-header is hidden, use header alignment. */
+ ((tool_header_hidden == false) ||
+ /* Don't prioritize the tool-header if both are hidden (behave as if both are visible).
+ * Without this, switching to a space with headers hidden will flip the alignment
+ * upon switching to a space with visible headers. */
+ (header_hidden && tool_header_hidden))) {
+ return tool_header_alignment;
+ }
+ if (header_alignment != -1) {
+ return header_alignment;
+ }
+ return fallback;
+}
+
+/**
+ * Notes on header alignment syncing.
+ *
+ * This is as involved as it is because:
+ *
+ * - There are currently 3 kinds of headers.
+ * - All headers can independently visible & flipped to another side
+ * (except for the tool-header that depends on the header visibility).
+ * - We don't want the space-switching button to flip when switching spaces.
+ * From the user perspective it feels like a bug to move the button you click on
+ * to the opposite side of the area.
+ * - The space-switcher may be on either the header or the tool-header
+ * depending on the tool-header visibility.
+ *
+ * How this works:
+ *
+ * - When headers match on both spaces, we copy the alignment
+ * from the previous regions to the next regions when syncing.
+ * - Otherwise detect the _primary_ header (the one that shows the space type)
+ * and use this to set alignment for the headers in the destination area.
+ * - Header & tool-header/footer may be on opposite sides, this is preserved when syncing.
+ */
+static void region_align_info_to_area_for_headers(
+ const struct RegionTypeAlignInfo *region_align_info_src,
+ const struct RegionTypeAlignInfo *region_align_info_dst,
+ ARegion *region_by_type[RGN_TYPE_LEN])
+{
+ /* Abbreviate access. */
+ const short header_alignment_src = region_align_info_src->by_type[RGN_TYPE_HEADER].alignment;
+ const short tool_header_alignment_src =
+ region_align_info_src->by_type[RGN_TYPE_TOOL_HEADER].alignment;
+
+ const bool tool_header_hidden_src = region_align_info_src->by_type[RGN_TYPE_TOOL_HEADER].hidden;
+
+ const short primary_header_alignment_src = region_alignment_from_header_and_tool_header_state(
+ region_align_info_src, -1);
+
+ /* Neither alignments are usable, don't sync. */
+ if (primary_header_alignment_src == -1) {
+ return;
+ }
+
+ const short header_alignment_dst = region_align_info_dst->by_type[RGN_TYPE_HEADER].alignment;
+ const short tool_header_alignment_dst =
+ region_align_info_dst->by_type[RGN_TYPE_TOOL_HEADER].alignment;
+ const short footer_alignment_dst = region_align_info_dst->by_type[RGN_TYPE_FOOTER].alignment;
+
+ const bool tool_header_hidden_dst = region_align_info_dst->by_type[RGN_TYPE_TOOL_HEADER].hidden;
+
+ /* New synchronized alignments to set (or ignore when left as -1). */
+ short header_alignment_sync = -1;
+ short tool_header_alignment_sync = -1;
+ short footer_alignment_sync = -1;
+
+ /* Both source/destination areas have same region configurations regarding headers.
+ * Simply copy the values. */
+ if (((header_alignment_src != -1) == (header_alignment_dst != -1)) &&
+ ((tool_header_alignment_src != -1) == (tool_header_alignment_dst != -1)) &&
+ (tool_header_hidden_src == tool_header_hidden_dst)) {
+ if (header_alignment_dst != -1) {
+ header_alignment_sync = header_alignment_src;
+ }
+ if (tool_header_alignment_dst != -1) {
+ tool_header_alignment_sync = tool_header_alignment_src;
+ }
+ }
+ else {
+ /* Not an exact match, check the space selector isn't moving. */
+ const short primary_header_alignment_dst = region_alignment_from_header_and_tool_header_state(
+ region_align_info_dst, -1);
+
+ if (primary_header_alignment_src != primary_header_alignment_dst) {
+ if ((header_alignment_dst != -1) && (tool_header_alignment_dst != -1)) {
+ if (header_alignment_dst == tool_header_alignment_dst) {
+ /* Apply to both. */
+ tool_header_alignment_sync = primary_header_alignment_src;
+ header_alignment_sync = primary_header_alignment_src;
+ }
+ else {
+ /* Keep on opposite sides. */
+ tool_header_alignment_sync = primary_header_alignment_src;
+ header_alignment_sync = (tool_header_alignment_sync == RGN_ALIGN_BOTTOM) ?
+ RGN_ALIGN_TOP :
+ RGN_ALIGN_BOTTOM;
+ }
+ }
+ else {
+ /* Apply what we can to regions that exist. */
+ if (header_alignment_dst != -1) {
+ header_alignment_sync = primary_header_alignment_src;
+ }
+ if (tool_header_alignment_dst != -1) {
+ tool_header_alignment_sync = primary_header_alignment_src;
+ }
+ }
+ }
+ }
+
+ if (footer_alignment_dst != -1) {
+ if ((header_alignment_dst != -1) && (header_alignment_dst == footer_alignment_dst)) {
+ /* Apply to both. */
+ footer_alignment_sync = primary_header_alignment_src;
+ }
+ else {
+ /* Keep on opposite sides. */
+ footer_alignment_sync = (primary_header_alignment_src == RGN_ALIGN_BOTTOM) ?
+ RGN_ALIGN_TOP :
+ RGN_ALIGN_BOTTOM;
+ }
+ }
+
+ /* Finally apply synchronized flags. */
+ if (header_alignment_sync != -1) {
+ ARegion *region = region_by_type[RGN_TYPE_HEADER];
+ if (region != NULL) {
+ region->alignment = RGN_ALIGN_ENUM_FROM_MASK(header_alignment_sync) |
+ RGN_ALIGN_FLAG_FROM_MASK(region->alignment);
+ }
+ }
+
+ if (tool_header_alignment_sync != -1) {
+ ARegion *region = region_by_type[RGN_TYPE_TOOL_HEADER];
+ if (region != NULL) {
+ region->alignment = RGN_ALIGN_ENUM_FROM_MASK(tool_header_alignment_sync) |
+ RGN_ALIGN_FLAG_FROM_MASK(region->alignment);
+ }
+ }
+
+ if (footer_alignment_sync != -1) {
+ ARegion *region = region_by_type[RGN_TYPE_FOOTER];
+ if (region != NULL) {
+ region->alignment = RGN_ALIGN_ENUM_FROM_MASK(footer_alignment_sync) |
+ RGN_ALIGN_FLAG_FROM_MASK(region->alignment);
+ }
+ }
+}
+
+static void region_align_info_to_area(
+ ScrArea *area, const struct RegionTypeAlignInfo region_align_info_src[RGN_TYPE_LEN])
+{
+ ARegion *region_by_type[RGN_TYPE_LEN] = {NULL};
+ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
+ const int index = region->regiontype;
+ if ((uint)index < RGN_TYPE_LEN) {
+ region_by_type[index] = region;
+ }
+ }
+
+ struct RegionTypeAlignInfo region_align_info_dst;
+ region_align_info_from_area(area, &region_align_info_dst);
+
+ if ((region_by_type[RGN_TYPE_HEADER] != NULL) ||
+ (region_by_type[RGN_TYPE_TOOL_HEADER] != NULL)) {
+ region_align_info_to_area_for_headers(
+ region_align_info_src, &region_align_info_dst, region_by_type);
+ }
+
+ /* Note that we could support other region types. */
+}
+
+/** \} */
+
/* *********** Space switching code *********** */
void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2)
@@ -2104,9 +2333,13 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi
* the space type defaults to in this case instead
* (needed for preferences to have space-type on bottom).
*/
- int header_alignment = ED_area_header_alignment_or_fallback(area, -1);
- const bool sync_header_alignment = ((header_alignment != -1) &&
- ((slold->link_flag & SPACE_FLAG_TYPE_TEMPORARY) == 0));
+
+ bool sync_header_alignment = false;
+ struct RegionTypeAlignInfo region_align_info[RGN_TYPE_LEN];
+ if ((slold != NULL) && (slold->link_flag & SPACE_FLAG_TYPE_TEMPORARY) == 0) {
+ region_align_info_from_area(area, region_align_info);
+ sync_header_alignment = true;
+ }
/* in some cases (opening temp space) we don't want to
* call area exit callback, so we temporarily unset it */
@@ -2180,28 +2413,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi
/* Sync header alignment. */
if (sync_header_alignment) {
- /* Spaces with footer. */
- if (st->spaceid == SPACE_TEXT) {
- LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
- if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
- region->alignment = header_alignment;
- }
- if (region->regiontype == RGN_TYPE_FOOTER) {
- int footer_alignment = (header_alignment == RGN_ALIGN_BOTTOM) ? RGN_ALIGN_TOP :
- RGN_ALIGN_BOTTOM;
- region->alignment = footer_alignment;
- break;
- }
- }
- }
- else {
- LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
- if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) {
- region->alignment = header_alignment;
- break;
- }
- }
- }
+ region_align_info_to_area(area, region_align_info);
}
ED_area_init(CTX_wm_manager(C), win, area);
@@ -2947,43 +3159,11 @@ int ED_area_headersize(void)
return U.widget_unit + (int)(UI_DPI_FAC * HEADER_PADDING_Y);
}
-int ED_area_header_alignment_or_fallback(const ScrArea *area, int fallback)
-{
- LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
- if (region->regiontype == RGN_TYPE_HEADER) {
- return region->alignment;
- }
- }
- return fallback;
-}
-
-int ED_area_header_alignment(const ScrArea *area)
-{
- return ED_area_header_alignment_or_fallback(
- area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP);
-}
-
int ED_area_footersize(void)
{
return ED_area_headersize();
}
-int ED_area_footer_alignment_or_fallback(const ScrArea *area, int fallback)
-{
- LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
- if (region->regiontype == RGN_TYPE_FOOTER) {
- return region->alignment;
- }
- }
- return fallback;
-}
-
-int ED_area_footer_alignment(const ScrArea *area)
-{
- return ED_area_footer_alignment_or_fallback(
- area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_TOP : RGN_ALIGN_BOTTOM);
-}
-
/**
* \return the final height of a global \a area, accounting for DPI.
*/
@@ -3084,19 +3264,17 @@ void ED_region_info_draw_multiline(ARegion *region,
rect.ymin = rect.ymax - header_height * num_lines;
/* setup scissor */
- GPU_scissor_get_i(scissor);
+ GPU_scissor_get(scissor);
GPU_scissor(rect.xmin, rect.ymin, BLI_rcti_size_x(&rect) + 1, BLI_rcti_size_y(&rect) + 1);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4fv(fill_color);
immRecti(pos, rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1);
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* text */
UI_FontThemeColor(fontid, TH_TEXT_HI);
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index d8d47fb01aa..a5d3c4842e6 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -296,8 +296,7 @@ static GPUBatch *batch_screen_edges_get(int *corner_len)
*/
static void scrarea_draw_shape_dark(ScrArea *area, char dir, uint pos)
{
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformColor4ub(0, 0, 0, 50);
draw_join_shape(area, dir, pos);
@@ -308,10 +307,8 @@ static void scrarea_draw_shape_dark(ScrArea *area, char dir, uint pos)
*/
static void scrarea_draw_shape_light(ScrArea *area, char UNUSED(dir), uint pos)
{
- GPU_blend_set_func(GPU_DST_COLOR, GPU_SRC_ALPHA);
- /* value 181 was hardly computed: 181~105 */
- immUniformColor4ub(255, 255, 255, 50);
- /* draw_join_shape(area, dir); */
+ GPU_blend(GPU_BLEND_ALPHA);
+ immUniformColor4ub(255, 255, 255, 25);
immRectf(pos, area->v1->vec.x, area->v1->vec.y, area->v3->vec.x, area->v3->vec.y);
}
@@ -413,9 +410,7 @@ void ED_screen_draw_edges(wmWindow *win)
corner_scale = U.pixelsize * 8.0f;
edge_thickness = corner_scale * 0.21f;
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUBatch *batch = batch_screen_edges_get(&verts_per_corner);
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_AREA_EDGES);
@@ -427,7 +422,7 @@ void ED_screen_draw_edges(wmWindow *win)
drawscredge_area(area, winsize_x, winsize_y, edge_thickness);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
if (U.pixelsize <= 1.0f) {
GPU_scissor_test(false);
@@ -470,12 +465,12 @@ void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2)
break;
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
scrarea_draw_shape_dark(sa2, dir, pos);
scrarea_draw_shape_light(sa1, dira, pos);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
immUnbindProgram();
@@ -487,9 +482,7 @@ void ED_screen_draw_split_preview(ScrArea *area, const int dir, const float fac)
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* splitpoint */
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformColor4ub(255, 255, 255, 100);
@@ -531,7 +524,7 @@ void ED_screen_draw_split_preview(ScrArea *area, const int dir, const float fac)
immEnd();
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();
}
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 06e800433b1..dbf84cad80b 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1594,7 +1594,7 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
ED_clip_update_frame(bmain, scene->r.cfra);
/* this function applies the changes too */
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
/*
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index d4379262666..0e38340d3bc 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -634,8 +634,7 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
/* Premultiplied alpha blending. */
- GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA_PREMULT);
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
@@ -670,8 +669,6 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
GPU_texture_unbind(texture);
- GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
-
if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_VIEW)) {
GPU_matrix_pop();
}
@@ -729,8 +726,7 @@ static bool paint_draw_cursor_overlay(
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA_PREMULT);
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
@@ -757,8 +753,6 @@ static bool paint_draw_cursor_overlay(
immUnbindProgram();
- GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
-
if (do_pop) {
GPU_matrix_pop();
}
@@ -781,7 +775,8 @@ static bool paint_draw_alpha_overlay(UnifiedPaintSettings *ups,
bool alpha_overlay_active = false;
ePaintOverlayControlFlags flags = BKE_paint_get_overlay_flags();
- gpuPushAttr(GPU_DEPTH_BUFFER_BIT | GPU_BLEND_BIT);
+ eGPUBlend blend_state = GPU_blend_get();
+ bool depth_test = GPU_depth_test_enabled();
/* Translate to region. */
GPU_matrix_push();
@@ -811,7 +806,8 @@ static bool paint_draw_alpha_overlay(UnifiedPaintSettings *ups,
}
GPU_matrix_pop();
- gpuPopAttr();
+ GPU_blend(blend_state);
+ GPU_depth_test(depth_test);
return alpha_overlay_active;
}
@@ -922,7 +918,7 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc)
PaintCurvePoint *cp = pc->points;
GPU_line_smooth(true);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* Draw the bezier handles and the curve segment between the current and next point. */
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -983,7 +979,7 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc)
draw_rect_point(
pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
immUnbindProgram();
@@ -1762,9 +1758,6 @@ static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorCont
GPU_matrix_pop();
- /* This Cloth brush cursor overlay always works in cursor space. */
- paint_cursor_drawing_setup_cursor_space(pcontext);
-
GPU_matrix_pop_projection();
wmWindowViewport(pcontext->win);
}
@@ -1842,7 +1835,7 @@ static void paint_cursor_update_anchored_location(PaintCursorContext *pcontext)
static void paint_cursor_setup_2D_drawing(PaintCursorContext *pcontext)
{
GPU_line_width(2.0f);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
pcontext->pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -1852,7 +1845,7 @@ static void paint_cursor_setup_2D_drawing(PaintCursorContext *pcontext)
static void paint_cursor_setup_3D_drawing(PaintCursorContext *pcontext)
{
GPU_line_width(2.0f);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
pcontext->pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@@ -1862,7 +1855,7 @@ static void paint_cursor_setup_3D_drawing(PaintCursorContext *pcontext)
static void paint_cursor_restore_drawing_state(void)
{
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 431ab998f62..d2ae6912fc3 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -438,7 +438,7 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda
if (pop) {
GPU_line_smooth(true);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
@@ -467,7 +467,7 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index db7de01bee5..456c1f61cb1 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -407,7 +407,6 @@ typedef struct ProjPaintState {
SpinLock *tile_lock;
Mesh *me_eval;
- bool me_eval_free;
int totlooptri_eval;
int totloop_eval;
int totpoly_eval;
@@ -4033,27 +4032,14 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
CustomData_MeshMasks cddata_masks = scene_eval->customdata_mask;
cddata_masks.fmask |= CD_MASK_MTFACE;
cddata_masks.lmask |= CD_MASK_MLOOPUV;
-
- /* Workaround for subsurf selection, try the display mesh first */
- if (ps->source == PROJ_SRC_IMAGE_CAM) {
- /* using render mesh, assume only camera was rendered from */
- ps->me_eval = mesh_create_eval_final_render(depsgraph, scene_eval, ob_eval, &cddata_masks);
- ps->me_eval_free = true;
- }
- else {
- if (ps->do_face_sel) {
- cddata_masks.vmask |= CD_MASK_ORIGINDEX;
- cddata_masks.emask |= CD_MASK_ORIGINDEX;
- cddata_masks.pmask |= CD_MASK_ORIGINDEX;
- }
- ps->me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks);
- ps->me_eval_free = false;
+ if (ps->do_face_sel) {
+ cddata_masks.vmask |= CD_MASK_ORIGINDEX;
+ cddata_masks.emask |= CD_MASK_ORIGINDEX;
+ cddata_masks.pmask |= CD_MASK_ORIGINDEX;
}
+ ps->me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks);
if (!CustomData_has_layer(&ps->me_eval->ldata, CD_MLOOPUV)) {
- if (ps->me_eval_free) {
- BKE_id_free(NULL, ps->me_eval);
- }
ps->me_eval = NULL;
return false;
}
@@ -4636,9 +4622,6 @@ static void project_paint_end(ProjPaintState *ps)
MEM_freeN(ps->cavities);
}
- if (ps->me_eval_free) {
- BKE_id_free(NULL, ps->me_eval);
- }
ps->me_eval = NULL;
}
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 90b0f017bd6..52cdebf3fd5 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -143,7 +143,7 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata
if (stroke && brush) {
GPU_line_smooth(true);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
ARegion *region = stroke->vc.region;
@@ -161,7 +161,7 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
}
@@ -997,7 +997,19 @@ static void stroke_done(bContext *C, wmOperator *op)
/* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
bool paint_space_stroke_enabled(Brush *br, ePaintMode mode)
{
- return (br->flag & BRUSH_SPACE) && paint_supports_dynamic_size(br, mode);
+ if ((br->flag & BRUSH_SPACE) == 0) {
+ return false;
+ }
+
+ if (br->sculpt_tool == SCULPT_TOOL_CLOTH) {
+ /* The Cloth Brush is a special case for stroke spacing. Even if it has grab modes which do
+ * not support dynamic size, stroke spacing needs to be enabled so it is possible to control
+ * whether the simulation runs constantly or only when the brush moves when using the cloth
+ * grab brushes. */
+ return true;
+ }
+
+ return paint_supports_dynamic_size(br, mode);
}
static bool sculpt_is_grab_tool(Brush *br)
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index d68b1226b40..e1c1b8ee5fb 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -275,6 +275,19 @@ void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3])
SCULPT_vertex_normal_get(ss, SCULPT_active_vertex_get(ss), normal);
}
+float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss,
+ const int deform_target,
+ PBVHVertexIter *iter)
+{
+ switch (deform_target) {
+ case BRUSH_DEFORM_TARGET_GEOMETRY:
+ return iter->co;
+ case BRUSH_DEFORM_TARGET_CLOTH_SIM:
+ return ss->cache->cloth_sim->deformation_pos[iter->index];
+ }
+ return iter->co;
+}
+
/* Sculpt Face Sets and Visibility. */
int SCULPT_active_face_set_get(SculptSession *ss)
@@ -2331,7 +2344,7 @@ static float brush_strength(const Sculpt *sd,
}
case SCULPT_TOOL_SMOOTH:
- return alpha * pressure * feather;
+ return flip * alpha * pressure * feather;
case SCULPT_TOOL_PINCH:
if (flip > 0.0f) {
@@ -5690,6 +5703,16 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
SCULPT_pose_brush_init(sd, ob, ss, brush);
}
+ if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
+ if (!ss->cache->cloth_sim) {
+ ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(ss, brush, 1.0f, 0.0f, false);
+ SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
+ SCULPT_cloth_brush_build_nodes_constraints(
+ sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
+ }
+ SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
+ }
+
bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN;
/* Apply one type of brush action. */
@@ -5828,6 +5851,12 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
do_gravity(sd, ob, nodes, totnode, sd->gravity_factor);
}
+ if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
+ if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
+ SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
+ }
+ }
+
MEM_SAFE_FREE(nodes);
/* Update average stroke position. */
@@ -6365,14 +6394,15 @@ void SCULPT_cache_free(StrokeCache *cache)
MEM_SAFE_FREE(cache->surface_smooth_laplacian_disp);
MEM_SAFE_FREE(cache->layer_displacement_factor);
MEM_SAFE_FREE(cache->prev_colors);
+ MEM_SAFE_FREE(cache->detail_directions);
if (cache->pose_ik_chain) {
SCULPT_pose_ik_chain_free(cache->pose_ik_chain);
}
for (int i = 0; i < PAINT_SYMM_AREAS; i++) {
- if (cache->bdata[i]) {
- SCULPT_boundary_data_free(cache->bdata[i]);
+ if (cache->boundaries[i]) {
+ SCULPT_boundary_data_free(cache->boundaries[i]);
}
}
@@ -7125,6 +7155,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
/* Update the active vertex of the SculptSession. */
ss->active_vertex_index = srd.active_vertex_index;
+ SCULPT_vertex_random_access_ensure(ss);
copy_v3_v3(out->active_vertex_co, SCULPT_active_vertex_co_get(ss));
switch (BKE_pbvh_type(ss->pbvh)) {
@@ -7306,7 +7337,8 @@ static void sculpt_brush_stroke_init(bContext *C, wmOperator *op)
need_mask = true;
}
- if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
+ if (brush->sculpt_tool == SCULPT_TOOL_CLOTH ||
+ brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
need_mask = true;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index f65c64d6d78..5e01e034715 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -130,38 +130,39 @@ static int sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss,
* deformations usually need in the boundary. */
static int BOUNDARY_INDICES_BLOCK_SIZE = 300;
-static void sculpt_boundary_index_add(SculptBoundary *bdata,
+static void sculpt_boundary_index_add(SculptBoundary *boundary,
const int new_index,
const float distance,
GSet *included_vertices)
{
- bdata->vertices[bdata->num_vertices] = new_index;
- if (bdata->distance) {
- bdata->distance[new_index] = distance;
+ boundary->vertices[boundary->num_vertices] = new_index;
+ if (boundary->distance) {
+ boundary->distance[new_index] = distance;
}
if (included_vertices) {
BLI_gset_add(included_vertices, POINTER_FROM_INT(new_index));
}
- bdata->num_vertices++;
- if (bdata->num_vertices >= bdata->vertices_capacity) {
- bdata->vertices_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
- bdata->vertices = MEM_reallocN_id(
- bdata->vertices, bdata->vertices_capacity * sizeof(int), "boundary indices");
+ boundary->num_vertices++;
+ if (boundary->num_vertices >= boundary->vertices_capacity) {
+ boundary->vertices_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
+ boundary->vertices = MEM_reallocN_id(
+ boundary->vertices, boundary->vertices_capacity * sizeof(int), "boundary indices");
}
};
-static void sculpt_boundary_preview_edge_add(SculptBoundary *bdata, const int v1, const int v2)
+static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary, const int v1, const int v2)
{
- bdata->edges[bdata->num_edges].v1 = v1;
- bdata->edges[bdata->num_edges].v2 = v2;
- bdata->num_edges++;
+ boundary->edges[boundary->num_edges].v1 = v1;
+ boundary->edges[boundary->num_edges].v2 = v2;
+ boundary->num_edges++;
- if (bdata->num_edges >= bdata->edges_capacity) {
- bdata->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
- bdata->edges = MEM_reallocN_id(
- bdata->edges, bdata->edges_capacity * sizeof(SculptBoundaryPreviewEdge), "boundary edges");
+ if (boundary->num_edges >= boundary->edges_capacity) {
+ boundary->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
+ boundary->edges = MEM_reallocN_id(boundary->edges,
+ boundary->edges_capacity * sizeof(SculptBoundaryPreviewEdge),
+ "boundary edges");
}
};
@@ -203,7 +204,7 @@ static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss,
*/
typedef struct BoundaryFloodFillData {
- SculptBoundary *bdata;
+ SculptBoundary *boundary;
GSet *included_vertices;
EdgeSet *preview_edges;
@@ -215,15 +216,16 @@ static bool boundary_floodfill_cb(
SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
{
BoundaryFloodFillData *data = userdata;
- SculptBoundary *bdata = data->bdata;
+ SculptBoundary *boundary = data->boundary;
if (SCULPT_vertex_is_boundary(ss, to_v)) {
const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v),
SCULPT_vertex_co_get(ss, to_v));
- const float distance_boundary_to_dst = bdata->distance ? bdata->distance[from_v] + edge_len :
- 0.0f;
- sculpt_boundary_index_add(bdata, to_v, distance_boundary_to_dst, data->included_vertices);
+ const float distance_boundary_to_dst = boundary->distance ?
+ boundary->distance[from_v] + edge_len :
+ 0.0f;
+ sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices);
if (!is_duplicate) {
- sculpt_boundary_preview_edge_add(bdata, from_v, to_v);
+ sculpt_boundary_preview_edge_add(boundary, from_v, to_v);
}
return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v);
}
@@ -231,31 +233,32 @@ static bool boundary_floodfill_cb(
}
static void sculpt_boundary_indices_init(SculptSession *ss,
- SculptBoundary *bdata,
+ SculptBoundary *boundary,
const bool init_boundary_distances,
const int initial_boundary_index)
{
const int totvert = SCULPT_vertex_count_get(ss);
- bdata->vertices = MEM_malloc_arrayN(
+ boundary->vertices = MEM_malloc_arrayN(
BOUNDARY_INDICES_BLOCK_SIZE, sizeof(int), "boundary indices");
if (init_boundary_distances) {
- bdata->distance = MEM_calloc_arrayN(totvert, sizeof(float), "boundary distances");
+ boundary->distance = MEM_calloc_arrayN(totvert, sizeof(float), "boundary distances");
}
- bdata->edges = MEM_malloc_arrayN(
+ boundary->edges = MEM_malloc_arrayN(
BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge), "boundary edges");
GSet *included_vertices = BLI_gset_int_new_ex("included vertices", BOUNDARY_INDICES_BLOCK_SIZE);
SculptFloodFill flood;
SCULPT_floodfill_init(ss, &flood);
- bdata->initial_vertex = initial_boundary_index;
- copy_v3_v3(bdata->initial_vertex_position, SCULPT_vertex_co_get(ss, bdata->initial_vertex));
- sculpt_boundary_index_add(bdata, initial_boundary_index, 0.0f, included_vertices);
+ boundary->initial_vertex = initial_boundary_index;
+ copy_v3_v3(boundary->initial_vertex_position,
+ SCULPT_vertex_co_get(ss, boundary->initial_vertex));
+ sculpt_boundary_index_add(boundary, initial_boundary_index, 0.0f, included_vertices);
SCULPT_floodfill_add_initial(&flood, initial_boundary_index);
BoundaryFloodFillData fdata = {
- .bdata = bdata,
+ .boundary = boundary,
.included_vertices = included_vertices,
.last_visited_vertex = BOUNDARY_VERTEX_NONE,
@@ -271,8 +274,8 @@ static void sculpt_boundary_indices_init(SculptSession *ss,
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, fdata.last_visited_vertex, ni) {
if (BLI_gset_haskey(included_vertices, POINTER_FROM_INT(ni.index)) &&
sculpt_boundary_is_vertex_in_editable_boundary(ss, ni.index)) {
- sculpt_boundary_preview_edge_add(bdata, fdata.last_visited_vertex, ni.index);
- bdata->forms_loop = true;
+ sculpt_boundary_preview_edge_add(boundary, fdata.last_visited_vertex, ni.index);
+ boundary->forms_loop = true;
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
@@ -288,7 +291,7 @@ static void sculpt_boundary_indices_init(SculptSession *ss,
* the closest one.
*/
static void sculpt_boundary_edit_data_init(SculptSession *ss,
- SculptBoundary *bdata,
+ SculptBoundary *boundary,
const int initial_vertex,
const float radius)
{
@@ -296,12 +299,12 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
const bool has_duplicates = BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
- bdata->edit_info = MEM_malloc_arrayN(
+ boundary->edit_info = MEM_malloc_arrayN(
totvert, sizeof(SculptBoundaryEditInfo), "Boundary edit info");
for (int i = 0; i < totvert; i++) {
- bdata->edit_info[i].original_vertex = BOUNDARY_VERTEX_NONE;
- bdata->edit_info[i].num_propagation_steps = BOUNDARY_STEPS_NONE;
+ boundary->edit_info[i].original_vertex = BOUNDARY_VERTEX_NONE;
+ boundary->edit_info[i].num_propagation_steps = BOUNDARY_STEPS_NONE;
}
GSQueue *current_iteration = BLI_gsqueue_new(sizeof(int));
@@ -310,23 +313,23 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
/* Initialized the first iteration with the vertices already in the boundary. This is propagation
* step 0. */
BLI_bitmap *visited_vertices = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_vertices");
- for (int i = 0; i < bdata->num_vertices; i++) {
- bdata->edit_info[bdata->vertices[i]].original_vertex = bdata->vertices[i];
- bdata->edit_info[bdata->vertices[i]].num_propagation_steps = 0;
+ for (int i = 0; i < boundary->num_vertices; i++) {
+ boundary->edit_info[boundary->vertices[i]].original_vertex = boundary->vertices[i];
+ boundary->edit_info[boundary->vertices[i]].num_propagation_steps = 0;
/* This ensures that all duplicate vertices in the boundary have the same original_vertex
* index, so the deformation for them will be the same. */
if (has_duplicates) {
SculptVertexNeighborIter ni_duplis;
- SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, bdata->vertices[i], ni_duplis) {
+ SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, boundary->vertices[i], ni_duplis) {
if (ni_duplis.is_duplicate) {
- bdata->edit_info[ni_duplis.index].original_vertex = bdata->vertices[i];
+ boundary->edit_info[ni_duplis.index].original_vertex = boundary->vertices[i];
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
}
- BLI_gsqueue_push(current_iteration, &bdata->vertices[i]);
+ BLI_gsqueue_push(current_iteration, &boundary->vertices[i]);
}
int num_propagation_steps = 0;
@@ -336,7 +339,7 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
/* This steps is further away from the boundary than the brush radius, so stop adding more
* steps. */
if (accum_distance > radius) {
- bdata->max_propagation_steps = num_propagation_steps;
+ boundary->max_propagation_steps = num_propagation_steps;
break;
}
@@ -346,19 +349,20 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
SculptVertexNeighborIter ni;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
- if (bdata->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) {
- bdata->edit_info[ni.index].original_vertex = bdata->edit_info[from_v].original_vertex;
+ if (boundary->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) {
+ boundary->edit_info[ni.index].original_vertex =
+ boundary->edit_info[from_v].original_vertex;
BLI_BITMAP_ENABLE(visited_vertices, ni.index);
if (ni.is_duplicate) {
/* Grids duplicates handling. */
- bdata->edit_info[ni.index].num_propagation_steps =
- bdata->edit_info[from_v].num_propagation_steps;
+ boundary->edit_info[ni.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps;
}
else {
- bdata->edit_info[ni.index].num_propagation_steps =
- bdata->edit_info[from_v].num_propagation_steps + 1;
+ boundary->edit_info[ni.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps + 1;
BLI_gsqueue_push(next_iteration, &ni.index);
@@ -370,10 +374,10 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
SculptVertexNeighborIter ni_duplis;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) {
if (ni_duplis.is_duplicate) {
- bdata->edit_info[ni_duplis.index].original_vertex =
- bdata->edit_info[from_v].original_vertex;
- bdata->edit_info[ni_duplis.index].num_propagation_steps =
- bdata->edit_info[from_v].num_propagation_steps + 1;
+ boundary->edit_info[ni_duplis.index].original_vertex =
+ boundary->edit_info[from_v].original_vertex;
+ boundary->edit_info[ni_duplis.index].num_propagation_steps =
+ boundary->edit_info[from_v].num_propagation_steps + 1;
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
@@ -381,9 +385,9 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
/* Check the distance using the vertex that was propagated from the initial vertex that
* was used to initialize the boundary. */
- if (bdata->edit_info[from_v].original_vertex == initial_vertex) {
- bdata->pivot_vertex = ni.index;
- copy_v3_v3(bdata->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
+ if (boundary->edit_info[from_v].original_vertex == initial_vertex) {
+ boundary->pivot_vertex = ni.index;
+ copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v),
SCULPT_vertex_co_get(ss, ni.index));
}
@@ -419,7 +423,7 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
* on the brush curve and its propagation steps. The falloff goes from the boundary into the mesh.
*/
static void sculpt_boundary_falloff_factor_init(SculptSession *ss,
- SculptBoundary *bdata,
+ SculptBoundary *boundary,
Brush *brush,
const float radius)
{
@@ -427,24 +431,24 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss,
BKE_curvemapping_init(brush->curve);
for (int i = 0; i < totvert; i++) {
- if (bdata->edit_info[i].num_propagation_steps != -1) {
- bdata->edit_info[i].strength_factor = BKE_brush_curve_strength(
- brush, bdata->edit_info[i].num_propagation_steps, bdata->max_propagation_steps);
+ if (boundary->edit_info[i].num_propagation_steps != -1) {
+ boundary->edit_info[i].strength_factor = BKE_brush_curve_strength(
+ brush, boundary->edit_info[i].num_propagation_steps, boundary->max_propagation_steps);
}
- if (bdata->edit_info[i].original_vertex == bdata->initial_vertex) {
+ if (boundary->edit_info[i].original_vertex == boundary->initial_vertex) {
/* All vertices that are propagated from the original vertex won't be affected by the
* boundary falloff, so there is no need to calculate anything else. */
continue;
}
- if (!bdata->distance) {
+ if (!boundary->distance) {
/* There are falloff modes that do not require to modify the previously calculated falloff
* based on boundary distances. */
continue;
}
- const float boundary_distance = bdata->distance[bdata->edit_info[i].original_vertex];
+ const float boundary_distance = boundary->distance[boundary->edit_info[i].original_vertex];
float falloff_distance = 0.0f;
float direction = 1.0f;
@@ -471,8 +475,8 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss,
BLI_assert(false);
}
- bdata->edit_info[i].strength_factor *= direction * BKE_brush_curve_strength(
- brush, falloff_distance, radius);
+ boundary->edit_info[i].strength_factor *= direction * BKE_brush_curve_strength(
+ brush, falloff_distance, radius);
}
}
@@ -501,116 +505,118 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object,
return NULL;
}
- SculptBoundary *bdata = MEM_callocN(sizeof(SculptBoundary), "Boundary edit data");
+ SculptBoundary *boundary = MEM_callocN(sizeof(SculptBoundary), "Boundary edit data");
const bool init_boundary_distances = brush->boundary_falloff_type !=
BRUSH_BOUNDARY_FALLOFF_CONSTANT;
- sculpt_boundary_indices_init(ss, bdata, init_boundary_distances, boundary_initial_vertex);
+ sculpt_boundary_indices_init(ss, boundary, init_boundary_distances, boundary_initial_vertex);
const float boundary_radius = radius * (1.0f + brush->boundary_offset);
- sculpt_boundary_edit_data_init(ss, bdata, boundary_initial_vertex, boundary_radius);
+ sculpt_boundary_edit_data_init(ss, boundary, boundary_initial_vertex, boundary_radius);
- return bdata;
+ return boundary;
}
-void SCULPT_boundary_data_free(SculptBoundary *bdata)
+void SCULPT_boundary_data_free(SculptBoundary *boundary)
{
- MEM_SAFE_FREE(bdata->vertices);
- MEM_SAFE_FREE(bdata->distance);
- MEM_SAFE_FREE(bdata->edit_info);
- MEM_SAFE_FREE(bdata->bend.pivot_positions);
- MEM_SAFE_FREE(bdata->bend.pivot_rotation_axis);
- MEM_SAFE_FREE(bdata->slide.directions);
- MEM_SAFE_FREE(bdata);
+ MEM_SAFE_FREE(boundary->vertices);
+ MEM_SAFE_FREE(boundary->distance);
+ MEM_SAFE_FREE(boundary->edit_info);
+ MEM_SAFE_FREE(boundary->bend.pivot_positions);
+ MEM_SAFE_FREE(boundary->bend.pivot_rotation_axis);
+ MEM_SAFE_FREE(boundary->slide.directions);
+ MEM_SAFE_FREE(boundary);
}
/* These functions initialize the required vectors for the desired deformation using the
* SculptBoundaryEditInfo. They calculate the data using the vertices that have the
* max_propagation_steps value and them this data is copied to the rest of the vertices using the
* original vertex index. */
-static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bdata)
+static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *boundary)
{
const int totvert = SCULPT_vertex_count_get(ss);
- bdata->bend.pivot_rotation_axis = MEM_calloc_arrayN(
+ boundary->bend.pivot_rotation_axis = MEM_calloc_arrayN(
totvert, 3 * sizeof(float), "pivot rotation axis");
- bdata->bend.pivot_positions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "pivot positions");
+ boundary->bend.pivot_positions = MEM_calloc_arrayN(
+ totvert, 3 * sizeof(float), "pivot positions");
for (int i = 0; i < totvert; i++) {
- if (bdata->edit_info[i].num_propagation_steps == bdata->max_propagation_steps) {
+ if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
float dir[3];
float normal[3];
SCULPT_vertex_normal_get(ss, i, normal);
sub_v3_v3v3(dir,
- SCULPT_vertex_co_get(ss, bdata->edit_info[i].original_vertex),
+ SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
SCULPT_vertex_co_get(ss, i));
cross_v3_v3v3(
- bdata->bend.pivot_rotation_axis[bdata->edit_info[i].original_vertex], dir, normal);
- normalize_v3(bdata->bend.pivot_rotation_axis[bdata->edit_info[i].original_vertex]);
- copy_v3_v3(bdata->bend.pivot_positions[bdata->edit_info[i].original_vertex],
+ boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal);
+ normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
+ copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex],
SCULPT_vertex_co_get(ss, i));
}
}
for (int i = 0; i < totvert; i++) {
- if (bdata->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
- copy_v3_v3(bdata->bend.pivot_positions[i],
- bdata->bend.pivot_positions[bdata->edit_info[i].original_vertex]);
- copy_v3_v3(bdata->bend.pivot_rotation_axis[i],
- bdata->bend.pivot_rotation_axis[bdata->edit_info[i].original_vertex]);
+ if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
+ copy_v3_v3(boundary->bend.pivot_positions[i],
+ boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]);
+ copy_v3_v3(boundary->bend.pivot_rotation_axis[i],
+ boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
}
}
}
-static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *bdata)
+static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *boundary)
{
const int totvert = SCULPT_vertex_count_get(ss);
- bdata->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions");
+ boundary->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions");
for (int i = 0; i < totvert; i++) {
- if (bdata->edit_info[i].num_propagation_steps == bdata->max_propagation_steps) {
- sub_v3_v3v3(bdata->slide.directions[bdata->edit_info[i].original_vertex],
- SCULPT_vertex_co_get(ss, bdata->edit_info[i].original_vertex),
+ if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
+ sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex],
+ SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
SCULPT_vertex_co_get(ss, i));
- normalize_v3(bdata->slide.directions[bdata->edit_info[i].original_vertex]);
+ normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]);
}
}
for (int i = 0; i < totvert; i++) {
- if (bdata->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
- copy_v3_v3(bdata->slide.directions[i],
- bdata->slide.directions[bdata->edit_info[i].original_vertex]);
+ if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
+ copy_v3_v3(boundary->slide.directions[i],
+ boundary->slide.directions[boundary->edit_info[i].original_vertex]);
}
}
}
-static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *bdata)
+static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *boundary)
{
- zero_v3(bdata->twist.pivot_position);
- float(*poly_verts)[3] = MEM_malloc_arrayN(bdata->num_vertices, sizeof(float) * 3, "poly verts");
- for (int i = 0; i < bdata->num_vertices; i++) {
- add_v3_v3(bdata->twist.pivot_position, SCULPT_vertex_co_get(ss, bdata->vertices[i]));
- copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, bdata->vertices[i]));
+ zero_v3(boundary->twist.pivot_position);
+ float(*poly_verts)[3] = MEM_malloc_arrayN(
+ boundary->num_vertices, sizeof(float) * 3, "poly verts");
+ for (int i = 0; i < boundary->num_vertices; i++) {
+ add_v3_v3(boundary->twist.pivot_position, SCULPT_vertex_co_get(ss, boundary->vertices[i]));
+ copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, boundary->vertices[i]));
}
- mul_v3_fl(bdata->twist.pivot_position, 1.0f / bdata->num_vertices);
- if (bdata->forms_loop) {
- normal_poly_v3(bdata->twist.rotation_axis, poly_verts, bdata->num_vertices);
+ mul_v3_fl(boundary->twist.pivot_position, 1.0f / boundary->num_vertices);
+ if (boundary->forms_loop) {
+ normal_poly_v3(boundary->twist.rotation_axis, poly_verts, boundary->num_vertices);
}
else {
- sub_v3_v3v3(bdata->twist.rotation_axis,
- SCULPT_vertex_co_get(ss, bdata->pivot_vertex),
- SCULPT_vertex_co_get(ss, bdata->initial_vertex));
- normalize_v3(bdata->twist.rotation_axis);
+ sub_v3_v3v3(boundary->twist.rotation_axis,
+ SCULPT_vertex_co_get(ss, boundary->pivot_vertex),
+ SCULPT_vertex_co_get(ss, boundary->initial_vertex));
+ normalize_v3(boundary->twist.rotation_axis);
}
MEM_freeN(poly_verts);
}
static float sculpt_boundary_displacement_from_grab_delta_get(SculptSession *ss,
- SculptBoundary *bdata)
+ SculptBoundary *boundary)
{
float plane[4];
float pos[3];
float normal[3];
- sub_v3_v3v3(normal, ss->cache->initial_location, bdata->initial_pivot_position);
+ sub_v3_v3v3(normal, ss->cache->initial_location, boundary->initial_pivot_position);
normalize_v3(normal);
plane_from_point_normal_v3(plane, ss->cache->initial_location, normal);
add_v3_v3v3(pos, ss->cache->initial_location, ss->cache->grab_delta_symmetry);
@@ -625,8 +631,9 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
const int symm_area = ss->cache->mirror_symmetry_pass;
- SculptBoundary *bdata = ss->cache->bdata[symm_area];
+ SculptBoundary *boundary = ss->cache->boundaries[symm_area];
const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+ const Brush *brush = data->brush;
const float strength = ss->cache->bstrength;
@@ -634,7 +641,7 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
- const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, bdata);
+ const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
float angle_factor = disp / ss->cache->radius;
/* Angle Snapping when inverting the brush. */
if (ss->cache->invert) {
@@ -645,17 +652,19 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (bdata->edit_info[vd.index].num_propagation_steps != -1) {
+ if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(orig_data.co, bdata->initial_vertex_position, symm)) {
+ if (SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
float t_orig_co[3];
- sub_v3_v3v3(t_orig_co, orig_data.co, bdata->bend.pivot_positions[vd.index]);
- rotate_v3_v3v3fl(vd.co,
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
+ rotate_v3_v3v3fl(target_co,
t_orig_co,
- bdata->bend.pivot_rotation_axis[vd.index],
- angle * bdata->edit_info[vd.index].strength_factor * mask);
- add_v3_v3(vd.co, bdata->bend.pivot_positions[vd.index]);
+ boundary->bend.pivot_rotation_axis[vd.index],
+ angle * boundary->edit_info[vd.index].strength_factor * mask);
+ add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
}
}
@@ -673,8 +682,9 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
const int symm_area = ss->cache->mirror_symmetry_pass;
- SculptBoundary *bdata = ss->cache->bdata[symm_area];
+ SculptBoundary *boundary = ss->cache->boundaries[symm_area];
const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+ const Brush *brush = data->brush;
const float strength = ss->cache->bstrength;
@@ -682,19 +692,21 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
- const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, bdata);
+ const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (bdata->edit_info[vd.index].num_propagation_steps != -1) {
+ if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(orig_data.co, bdata->initial_vertex_position, symm)) {
+ if (SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- madd_v3_v3v3fl(vd.co,
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
orig_data.co,
- bdata->slide.directions[vd.index],
- bdata->edit_info[vd.index].strength_factor * disp * mask * strength);
+ boundary->slide.directions[vd.index],
+ boundary->edit_info[vd.index].strength_factor * disp * mask * strength);
}
}
@@ -712,8 +724,9 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
const int symm_area = ss->cache->mirror_symmetry_pass;
- SculptBoundary *bdata = ss->cache->bdata[symm_area];
+ SculptBoundary *boundary = ss->cache->boundaries[symm_area];
const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+ const Brush *brush = data->brush;
const float strength = ss->cache->bstrength;
@@ -721,21 +734,23 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
- const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, bdata);
+ const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (bdata->edit_info[vd.index].num_propagation_steps != -1) {
+ if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(orig_data.co, bdata->initial_vertex_position, symm)) {
+ if (SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
float normal[3];
normal_short_to_float_v3(normal, orig_data.no);
- madd_v3_v3v3fl(vd.co,
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
orig_data.co,
normal,
- bdata->edit_info[vd.index].strength_factor * disp * mask * strength);
+ boundary->edit_info[vd.index].strength_factor * disp * mask * strength);
}
}
@@ -753,8 +768,9 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
const int symm_area = ss->cache->mirror_symmetry_pass;
- SculptBoundary *bdata = ss->cache->bdata[symm_area];
+ SculptBoundary *boundary = ss->cache->boundaries[symm_area];
const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+ const Brush *brush = data->brush;
const float strength = ss->cache->bstrength;
@@ -765,14 +781,16 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (bdata->edit_info[vd.index].num_propagation_steps != -1) {
+ if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(orig_data.co, bdata->initial_vertex_position, symm)) {
+ if (SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- madd_v3_v3v3fl(vd.co,
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ madd_v3_v3v3fl(target_co,
orig_data.co,
ss->cache->grab_delta_symmetry,
- bdata->edit_info[vd.index].strength_factor * mask * strength);
+ boundary->edit_info[vd.index].strength_factor * mask * strength);
}
}
@@ -790,8 +808,9 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
const int symm_area = ss->cache->mirror_symmetry_pass;
- SculptBoundary *bdata = ss->cache->bdata[symm_area];
+ SculptBoundary *boundary = ss->cache->boundaries[symm_area];
const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+ const Brush *brush = data->brush;
const float strength = ss->cache->bstrength;
@@ -799,7 +818,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
- const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, bdata);
+ const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
float angle_factor = disp / ss->cache->radius;
/* Angle Snapping when inverting the brush. */
if (ss->cache->invert) {
@@ -810,17 +829,19 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (bdata->edit_info[vd.index].num_propagation_steps != -1) {
+ if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
SCULPT_orig_vert_data_update(&orig_data, &vd);
- if (SCULPT_check_vertex_pivot_symmetry(orig_data.co, bdata->initial_vertex_position, symm)) {
+ if (SCULPT_check_vertex_pivot_symmetry(
+ orig_data.co, boundary->initial_vertex_position, symm)) {
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
float t_orig_co[3];
- sub_v3_v3v3(t_orig_co, orig_data.co, bdata->twist.pivot_position);
- rotate_v3_v3v3fl(vd.co,
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
+ rotate_v3_v3v3fl(target_co,
t_orig_co,
- bdata->twist.rotation_axis,
- angle * mask * bdata->edit_info[vd.index].strength_factor);
- add_v3_v3(vd.co, bdata->twist.pivot_position);
+ boundary->twist.rotation_axis,
+ angle * mask * boundary->edit_info[vd.index].strength_factor);
+ add_v3_v3(target_co, boundary->twist.pivot_position);
}
}
@@ -851,20 +872,20 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
sd, ob, location, ss->cache->radius_squared, false);
}
- ss->cache->bdata[symm_area] = SCULPT_boundary_data_init(
+ ss->cache->boundaries[symm_area] = SCULPT_boundary_data_init(
ob, brush, initial_vertex, ss->cache->initial_radius);
- if (ss->cache->bdata[symm_area]) {
+ if (ss->cache->boundaries[symm_area]) {
switch (brush->boundary_deform_type) {
case BRUSH_BOUNDARY_DEFORM_BEND:
- sculpt_boundary_bend_data_init(ss, ss->cache->bdata[symm_area]);
+ sculpt_boundary_bend_data_init(ss, ss->cache->boundaries[symm_area]);
break;
case BRUSH_BOUNDARY_DEFORM_EXPAND:
- sculpt_boundary_slide_data_init(ss, ss->cache->bdata[symm_area]);
+ sculpt_boundary_slide_data_init(ss, ss->cache->boundaries[symm_area]);
break;
case BRUSH_BOUNDARY_DEFORM_TWIST:
- sculpt_boundary_twist_data_init(ss, ss->cache->bdata[symm_area]);
+ sculpt_boundary_twist_data_init(ss, ss->cache->boundaries[symm_area]);
break;
case BRUSH_BOUNDARY_DEFORM_INFLATE:
case BRUSH_BOUNDARY_DEFORM_GRAB:
@@ -873,12 +894,12 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
}
sculpt_boundary_falloff_factor_init(
- ss, ss->cache->bdata[symm_area], brush, ss->cache->initial_radius);
+ ss, ss->cache->boundaries[symm_area], brush, ss->cache->initial_radius);
}
}
/* No active boundary under the cursor. */
- if (!ss->cache->bdata[symm_area]) {
+ if (!ss->cache->boundaries[symm_area]) {
return;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index 2637cb45906..9a3fbe474b8 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -134,6 +134,7 @@ static float cloth_brush_simulation_falloff_get(const Brush *brush,
#define CLOTH_SIMULATION_ITERATIONS 5
#define CLOTH_MAX_CONSTRAINTS_PER_VERTEX 1024
#define CLOTH_SIMULATION_TIME_STEP 0.01f
+#define CLOTH_DEFORMATION_TARGET_STRENGTH 0.35f
static bool cloth_brush_sim_has_length_constraint(SculptClothSimulation *cloth_sim,
const int v1,
@@ -297,15 +298,28 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
}
}
- if (cloth_is_deform_brush && len_squared < radius_squared) {
- const float fade = BKE_brush_curve_strength(brush, sqrtf(len_squared), ss->cache->radius);
- cloth_brush_add_deformation_constraint(data->cloth_sim, vd.index, fade);
+ if (brush && brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
+ /* The cloth brush works by applying forces in most of its modes, but some of them require
+ * deformation coordinates to make the simulation stable. */
+ if (cloth_is_deform_brush && len_squared < radius_squared) {
+ /* When a deform brush is used as part of the cloth brush, deformation constraints are
+ * created with different strengths and only inside the radius of the brush. */
+ const float fade = BKE_brush_curve_strength(brush, sqrtf(len_squared), ss->cache->radius);
+ cloth_brush_add_deformation_constraint(data->cloth_sim, vd.index, fade);
+ }
+ }
+ else if (data->cloth_sim->deformation_pos) {
+ /* Any other tool that target the cloth simulation handle the falloff in
+ * their own code when modifying the deformation coordinates of the simulation, so
+ * deformation constraints are created with a fixed strength for all vertices. */
+ cloth_brush_add_deformation_constraint(
+ data->cloth_sim, vd.index, CLOTH_DEFORMATION_TARGET_STRENGTH);
}
if (pin_simulation_boundary) {
const float sim_falloff = cloth_brush_simulation_falloff_get(
brush, ss->cache->initial_radius, ss->cache->location, vd.co);
- /* Vertex is inside the area of the simulation without any falloff aplied. */
+ /* Vertex is inside the area of the simulation without any falloff applied. */
if (sim_falloff < 1.0f) {
/* Create constraints with more strength the closer the vertex is to the simulation
* boundary. */
@@ -505,49 +519,6 @@ static ListBase *cloth_brush_collider_cache_create(Depsgraph *depsgraph)
return cache;
}
-static SculptClothSimulation *cloth_brush_simulation_create(SculptSession *ss,
- Brush *brush,
- const float cloth_mass,
- const float cloth_damping,
- const bool use_collisions)
-{
- const int totverts = SCULPT_vertex_count_get(ss);
- SculptClothSimulation *cloth_sim;
-
- cloth_sim = MEM_callocN(sizeof(SculptClothSimulation), "cloth constraints");
-
- cloth_sim->length_constraints = MEM_callocN(sizeof(SculptClothLengthConstraint) *
- CLOTH_LENGTH_CONSTRAINTS_BLOCK,
- "cloth length constraints");
- cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK;
-
- cloth_sim->acceleration = MEM_calloc_arrayN(
- totverts, sizeof(float[3]), "cloth sim acceleration");
- cloth_sim->pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim pos");
- cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim prev pos");
- cloth_sim->last_iteration_pos = MEM_calloc_arrayN(
- totverts, sizeof(float[3]), "cloth sim last iteration pos");
- cloth_sim->init_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim init pos");
- cloth_sim->length_constraint_tweak = MEM_calloc_arrayN(
- totverts, sizeof(float), "cloth sim length tweak");
-
- /* Brush can be NULL for tools that need the solver but don't rely on constraint to deformation
- * positions. */
- if (brush && SCULPT_is_cloth_deform_brush(brush)) {
- cloth_sim->deformation_pos = MEM_calloc_arrayN(
- totverts, sizeof(float[3]), "cloth sim deformation positions");
- }
-
- cloth_sim->mass = cloth_mass;
- cloth_sim->damping = cloth_damping;
-
- if (use_collisions) {
- cloth_sim->collider_list = cloth_brush_collider_cache_create(ss->depsgraph);
- }
-
- return cloth_sim;
-}
-
typedef struct ClothBrushCollision {
CollisionModifierData *col_data;
struct IsectRayPrecalc isect_precalc;
@@ -699,43 +670,6 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
BKE_pbvh_vertex_iter_end;
}
-static void cloth_brush_build_nodes_constraints(
- Sculpt *sd,
- Object *ob,
- PBVHNode **nodes,
- int totnode,
- SculptClothSimulation *cloth_sim,
- /* Cannot be const, because it is assigned to a non-const variable.
- * NOLINTNEXTLINE: readability-non-const-parameter. */
- float initial_location[3],
- const float radius)
-{
- Brush *brush = BKE_paint_brush(&sd->paint);
-
- /* TODO: Multi-threaded needs to be disabled for this task until implementing the optimization of
- * storing the constraints per node. */
- /* Currently all constrains are added to the same global array which can't be accessed from
- * different threads. */
- TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, false, totnode);
-
- cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints");
-
- SculptThreadedTaskData build_constraints_data = {
- .sd = sd,
- .ob = ob,
- .brush = brush,
- .nodes = nodes,
- .cloth_sim = cloth_sim,
- .cloth_sim_initial_location = initial_location,
- .cloth_sim_radius = radius,
- };
- BLI_task_parallel_range(
- 0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings);
-
- BLI_edgeset_free(cloth_sim->created_length_constraints);
-}
-
static void cloth_brush_satisfy_constraints(SculptSession *ss,
Brush *brush,
SculptClothSimulation *cloth_sim)
@@ -796,7 +730,7 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss,
}
}
-static void cloth_brush_do_simulation_step(
+void SCULPT_cloth_brush_do_simulation_step(
Sculpt *sd, Object *ob, SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
@@ -897,13 +831,113 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
}
/* Public functions. */
+SculptClothSimulation *SCULPT_cloth_brush_simulation_create(SculptSession *ss,
+ Brush *brush,
+ const float cloth_mass,
+ const float cloth_damping,
+ const bool use_collisions)
+{
+ const int totverts = SCULPT_vertex_count_get(ss);
+ SculptClothSimulation *cloth_sim;
+
+ cloth_sim = MEM_callocN(sizeof(SculptClothSimulation), "cloth constraints");
+
+ cloth_sim->length_constraints = MEM_callocN(sizeof(SculptClothLengthConstraint) *
+ CLOTH_LENGTH_CONSTRAINTS_BLOCK,
+ "cloth length constraints");
+ cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK;
+
+ cloth_sim->acceleration = MEM_calloc_arrayN(
+ totverts, sizeof(float[3]), "cloth sim acceleration");
+ cloth_sim->pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim pos");
+ cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim prev pos");
+ cloth_sim->last_iteration_pos = MEM_calloc_arrayN(
+ totverts, sizeof(float[3]), "cloth sim last iteration pos");
+ cloth_sim->init_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim init pos");
+ cloth_sim->length_constraint_tweak = MEM_calloc_arrayN(
+ totverts, sizeof(float), "cloth sim length tweak");
+
+ /* Brush can be NULL for tools that need the solver but don't rely on constraint to deformation
+ * positions. */
+ if (brush && SCULPT_is_cloth_deform_brush(brush)) {
+ cloth_sim->deformation_pos = MEM_calloc_arrayN(
+ totverts, sizeof(float[3]), "cloth sim deformation positions");
+ }
+
+ cloth_sim->mass = cloth_mass;
+ cloth_sim->damping = cloth_damping;
+
+ if (use_collisions) {
+ cloth_sim->collider_list = cloth_brush_collider_cache_create(ss->depsgraph);
+ }
+
+ return cloth_sim;
+}
+
+void SCULPT_cloth_brush_build_nodes_constraints(
+ Sculpt *sd,
+ Object *ob,
+ PBVHNode **nodes,
+ int totnode,
+ SculptClothSimulation *cloth_sim,
+ /* Cannot be const, because it is assigned to a non-const variable.
+ * NOLINTNEXTLINE: readability-non-const-parameter. */
+ float initial_location[3],
+ const float radius)
+{
+ Brush *brush = BKE_paint_brush(&sd->paint);
+
+ /* TODO: Multi-threaded needs to be disabled for this task until implementing the optimization of
+ * storing the constraints per node. */
+ /* Currently all constrains are added to the same global array which can't be accessed from
+ * different threads. */
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, false, totnode);
+
+ cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints");
+
+ SculptThreadedTaskData build_constraints_data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ .cloth_sim = cloth_sim,
+ .cloth_sim_initial_location = initial_location,
+ .cloth_sim_radius = radius,
+ };
+ BLI_task_parallel_range(
+ 0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings);
+
+ BLI_edgeset_free(cloth_sim->created_length_constraints);
+}
+
+void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation *cloth_sim)
+{
+ const int totverts = SCULPT_vertex_count_get(ss);
+ const bool has_deformation_pos = cloth_sim->deformation_pos != NULL;
+ for (int i = 0; i < totverts; i++) {
+ copy_v3_v3(cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i));
+ copy_v3_v3(cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i));
+ copy_v3_v3(cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i));
+ if (has_deformation_pos) {
+ copy_v3_v3(cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, i));
+ }
+ }
+}
+
+void SCULPT_cloth_brush_store_simulation_state(SculptSession *ss, SculptClothSimulation *cloth_sim)
+{
+ const int totverts = SCULPT_vertex_count_get(ss);
+ for (int i = 0; i < totverts; i++) {
+ copy_v3_v3(cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i));
+ }
+}
/* Main Brush Function. */
void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
- const int totverts = SCULPT_vertex_count_get(ss);
/* In the first brush step of each symmetry pass, build the constraints for the vertices in all
* nodes inside the simulation's limits. */
@@ -914,42 +948,32 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
/* The simulation structure only needs to be created on the first symmetry pass. */
if (SCULPT_stroke_is_first_brush_step(ss->cache) || !ss->cache->cloth_sim) {
- const bool is_cloth_deform_brush = SCULPT_is_cloth_deform_brush(brush);
- ss->cache->cloth_sim = cloth_brush_simulation_create(
+ ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
ss,
brush,
brush->cloth_mass,
brush->cloth_damping,
(brush->flag2 & BRUSH_CLOTH_USE_COLLISION));
- for (int i = 0; i < totverts; i++) {
- copy_v3_v3(ss->cache->cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i));
- copy_v3_v3(ss->cache->cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i));
- copy_v3_v3(ss->cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i));
- if (is_cloth_deform_brush) {
- copy_v3_v3(ss->cache->cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, i));
- }
- }
+ SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
}
/* Build the constraints. */
const float radius = ss->cache->initial_radius;
const float limit = radius + (radius * brush->cloth_sim_limit);
- cloth_brush_build_nodes_constraints(
+ SCULPT_cloth_brush_build_nodes_constraints(
sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, limit);
return;
}
/* Store the initial state in the simulation. */
- for (int i = 0; i < totverts; i++) {
- copy_v3_v3(ss->cache->cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i));
- }
+ SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
/* Apply forces to the vertices. */
cloth_brush_apply_brush_foces(sd, ob, nodes, totnode);
/* Update and write the simulation to the nodes. */
- cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
+ SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
}
void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim)
@@ -1043,11 +1067,20 @@ static EnumPropertyItem prop_cloth_filter_type[] = {
{CLOTH_FILTER_GRAVITY, "GRAVITY", 0, "Gravity", "Applies gravity to the simulation"},
{CLOTH_FILTER_INFLATE, "INFLATE", 0, "Inflate", "Inflates the cloth"},
{CLOTH_FILTER_EXPAND, "EXPAND", 0, "Expand", "Expands the cloth's dimensions"},
- {CLOTH_FILTER_PINCH,
- "PINCH",
- 0,
- "Pinch",
- "Pinches the cloth to the point were the cursor was when the filter started"},
+ {CLOTH_FILTER_PINCH, "PINCH", 0, "Pinch", "Pulls the cloth to the cursor's start position"},
+ {0, NULL, 0, NULL, NULL},
+};
+
+typedef enum eClothFilterForceAxis {
+ CLOTH_FILTER_FORCE_X = 1 << 0,
+ CLOTH_FILTER_FORCE_Y = 1 << 1,
+ CLOTH_FILTER_FORCE_Z = 1 << 2,
+} eClothFilterForceAxis;
+
+static EnumPropertyItem prop_cloth_filter_force_axis_items[] = {
+ {CLOTH_FILTER_FORCE_X, "X", 0, "X", "Apply force in the X axis"},
+ {CLOTH_FILTER_FORCE_Y, "Y", 0, "Y", "Apply force in the Y axis"},
+ {CLOTH_FILTER_FORCE_Z, "Z", 0, "Z", "Apply force in the Z axis"},
{0, NULL, 0, NULL, NULL},
};
@@ -1105,6 +1138,12 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata,
break;
}
+ for (int axis = 0; axis < 3; axis++) {
+ if (!ss->filter_cache->enabled_force_axis[axis]) {
+ force[axis] = 0.0f;
+ }
+ }
+
add_v3_v3(force, sculpt_gravity);
cloth_brush_apply_force_to_vertex(ss, cloth_sim, force, vd.index);
@@ -1161,7 +1200,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
0, ss->filter_cache->totnode, &data, cloth_filter_apply_forces_task_cb, &settings);
/* Update and write the simulation to the nodes. */
- cloth_brush_do_simulation_step(
+ SCULPT_cloth_brush_do_simulation_step(
sd, ob, ss->filter_cache->cloth_sim, ss->filter_cache->nodes, ss->filter_cache->totnode);
if (ss->deform_modifiers_active || ss->shapekey_active) {
@@ -1191,31 +1230,26 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
SCULPT_undo_push_begin("Cloth filter");
- SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS);
+ SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS);
const float cloth_mass = RNA_float_get(op->ptr, "cloth_mass");
const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping");
const bool use_collisions = RNA_boolean_get(op->ptr, "use_collisions");
- ss->filter_cache->cloth_sim = cloth_brush_simulation_create(
+ ss->filter_cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
ss, NULL, cloth_mass, cloth_damping, use_collisions);
copy_v3_v3(ss->filter_cache->cloth_sim_pinch_point, SCULPT_active_vertex_co_get(ss));
- const int totverts = SCULPT_vertex_count_get(ss);
- for (int i = 0; i < totverts; i++) {
- copy_v3_v3(ss->filter_cache->cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i));
- copy_v3_v3(ss->filter_cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i));
- copy_v3_v3(ss->filter_cache->cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i));
- }
+ SCULPT_cloth_brush_simulation_init(ss, ss->filter_cache->cloth_sim);
float origin[3] = {0.0f, 0.0f, 0.0f};
- cloth_brush_build_nodes_constraints(sd,
- ob,
- ss->filter_cache->nodes,
- ss->filter_cache->totnode,
- ss->filter_cache->cloth_sim,
- origin,
- FLT_MAX);
+ SCULPT_cloth_brush_build_nodes_constraints(sd,
+ ob,
+ ss->filter_cache->nodes,
+ ss->filter_cache->totnode,
+ ss->filter_cache->cloth_sim,
+ origin,
+ FLT_MAX);
const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets");
if (use_face_sets) {
@@ -1225,6 +1259,11 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
ss->filter_cache->active_face_set = SCULPT_FACE_SET_NONE;
}
+ const int force_axis = RNA_enum_get(op->ptr, "force_axis");
+ ss->filter_cache->enabled_force_axis[0] = force_axis & CLOTH_FILTER_FORCE_X;
+ ss->filter_cache->enabled_force_axis[1] = force_axis & CLOTH_FILTER_FORCE_Y;
+ ss->filter_cache->enabled_force_axis[2] = force_axis & CLOTH_FILTER_FORCE_Z;
+
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -1252,6 +1291,12 @@ void SCULPT_OT_cloth_filter(struct wmOperatorType *ot)
"Operation that is going to be applied to the mesh");
RNA_def_float(
ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter Strength", -10.0f, 10.0f);
+ RNA_def_enum_flag(ot->srna,
+ "force_axis",
+ prop_cloth_filter_force_axis_items,
+ CLOTH_FILTER_FORCE_X | CLOTH_FILTER_FORCE_Y | CLOTH_FILTER_FORCE_Z,
+ "Force axis",
+ "Apply the force in the selected axis");
RNA_def_float(ot->srna,
"cloth_mass",
1.0f,
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index 2afa3556dd9..b9265380a35 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -71,6 +71,37 @@
#include <math.h>
#include <stdlib.h>
+/* Utils. */
+int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh)
+{
+ int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ if (!face_sets) {
+ return SCULPT_FACE_SET_NONE;
+ }
+
+ int next_face_set_id = 0;
+ for (int i = 0; i < mesh->totpoly; i++) {
+ next_face_set_id = max_ii(next_face_set_id, abs(face_sets[i]));
+ }
+ next_face_set_id++;
+
+ return next_face_set_id;
+}
+
+void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, const int new_id)
+{
+ int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS);
+ if (!face_sets) {
+ return;
+ }
+
+ for (int i = 0; i < mesh->totpoly; i++) {
+ if (face_sets[i] == SCULPT_FACE_SET_NONE) {
+ face_sets[i] = new_id;
+ }
+ }
+}
+
/* Draw Face Sets Brush. */
static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata,
@@ -901,6 +932,25 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static int sculpt_face_sets_change_visibility_invoke(bContext *C,
+ wmOperator *op,
+ const wmEvent *event)
+{
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+
+ /* Update the active vertex and Face Set using the cursor position to avoid relying on the paint
+ * cursor updates. */
+ SculptCursorGeometryInfo sgi;
+ float mouse[2];
+ mouse[0] = event->mval[0];
+ mouse[1] = event->mval[1];
+ SCULPT_vertex_random_access_ensure(ss);
+ SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
+
+ return sculpt_face_sets_change_visibility_exec(C, op);
+}
+
void SCULPT_OT_face_sets_change_visibility(wmOperatorType *ot)
{
/* Identifiers. */
@@ -910,6 +960,7 @@ void SCULPT_OT_face_sets_change_visibility(wmOperatorType *ot)
/* Api callbacks. */
ot->exec = sculpt_face_sets_change_visibility_exec;
+ ot->invoke = sculpt_face_sets_change_visibility_invoke;
ot->poll = SCULPT_mode_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
index 576536cac03..c5acf736f3e 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c
@@ -289,7 +289,7 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_CANCELLED;
}
- SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COLOR);
+ SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COLOR);
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index f9ae91fce7f..56e70a8d47a 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -50,6 +50,7 @@
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
+#include "ED_view3d.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
@@ -63,6 +64,39 @@
#include <math.h>
#include <stdlib.h>
+/* Filter orientation utils. */
+void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter_cache)
+{
+ switch (filter_cache->orientation) {
+ case SCULPT_FILTER_ORIENTATION_LOCAL:
+ /* Do nothing, Sculpt Mode already works in object space. */
+ break;
+ case SCULPT_FILTER_ORIENTATION_WORLD:
+ mul_mat3_m4_v3(filter_cache->obmat, r_v);
+ break;
+ case SCULPT_FILTER_ORIENTATION_VIEW:
+ mul_mat3_m4_v3(filter_cache->obmat, r_v);
+ mul_mat3_m4_v3(filter_cache->viewmat, r_v);
+ break;
+ }
+}
+
+void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cache)
+{
+ switch (filter_cache->orientation) {
+ case SCULPT_FILTER_ORIENTATION_LOCAL:
+ /* Do nothing, Sculpt Mode already works in object space. */
+ break;
+ case SCULPT_FILTER_ORIENTATION_WORLD:
+ mul_mat3_m4_v3(filter_cache->obmat_inv, r_v);
+ break;
+ case SCULPT_FILTER_ORIENTATION_VIEW:
+ mul_mat3_m4_v3(filter_cache->viewmat_inv, r_v);
+ mul_mat3_m4_v3(filter_cache->obmat_inv, r_v);
+ break;
+ }
+}
+
static void filter_cache_init_task_cb(void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict UNUSED(tls))
@@ -73,7 +107,7 @@ static void filter_cache_init_task_cb(void *__restrict userdata,
SCULPT_undo_push_node(data->ob, node, data->filter_undo_type);
}
-void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type)
+void SCULPT_filter_cache_init(bContext *C, Object *ob, Sculpt *sd, const int undo_type)
{
SculptSession *ss = ob->sculpt;
PBVH *pbvh = ob->sculpt->pbvh;
@@ -117,6 +151,16 @@ void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type)
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
BLI_task_parallel_range(
0, ss->filter_cache->totnode, &data, filter_cache_init_task_cb, &settings);
+
+ /* Setup orientation matrices. */
+ copy_m4_m4(ss->filter_cache->obmat, ob->obmat);
+ invert_m4_m4(ss->filter_cache->obmat_inv, ob->obmat);
+
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ViewContext vc;
+ ED_view3d_viewcontext_init(C, &vc, depsgraph);
+ copy_m4_m4(ss->filter_cache->viewmat, vc.rv3d->viewmat);
+ copy_m4_m4(ss->filter_cache->viewmat_inv, vc.rv3d->viewinv);
}
void SCULPT_filter_cache_free(SculptSession *ss)
@@ -132,7 +176,8 @@ void SCULPT_filter_cache_free(SculptSession *ss)
MEM_SAFE_FREE(ss->filter_cache->automask);
MEM_SAFE_FREE(ss->filter_cache->surface_smooth_laplacian_disp);
MEM_SAFE_FREE(ss->filter_cache->sharpen_factor);
- MEM_SAFE_FREE(ss->filter_cache->sharpen_detail_directions);
+ MEM_SAFE_FREE(ss->filter_cache->detail_directions);
+ MEM_SAFE_FREE(ss->filter_cache->limit_surface_co);
MEM_SAFE_FREE(ss->filter_cache);
}
@@ -146,6 +191,8 @@ typedef enum eSculptMeshFilterTypes {
MESH_FILTER_RELAX_FACE_SETS = 6,
MESH_FILTER_SURFACE_SMOOTH = 7,
MESH_FILTER_SHARPEN = 8,
+ MESH_FILTER_ENHANCE_DETAILS = 9,
+ MESH_FILTER_ERASE_DISPLACEMENT = 10,
} eSculptMeshFilterTypes;
static EnumPropertyItem prop_mesh_filter_types[] = {
@@ -166,6 +213,16 @@ static EnumPropertyItem prop_mesh_filter_types[] = {
"Surface Smooth",
"Smooth the surface of the mesh, preserving the volume"},
{MESH_FILTER_SHARPEN, "SHARPEN", 0, "Sharpen", "Sharpen the cavities of the mesh"},
+ {MESH_FILTER_ENHANCE_DETAILS,
+ "ENHANCE_DETAILS",
+ 0,
+ "Enhance Details",
+ "Enhance the high frequency surface detail"},
+ {MESH_FILTER_ERASE_DISPLACEMENT,
+ "ERASE_DISCPLACEMENT",
+ 0,
+ "Erase Displacement",
+ "Deletes the displacement of the Multires Modifier"},
{0, NULL, 0, NULL, NULL},
};
@@ -182,6 +239,25 @@ static EnumPropertyItem prop_mesh_filter_deform_axis_items[] = {
{0, NULL, 0, NULL, NULL},
};
+static EnumPropertyItem prop_mesh_filter_orientation_items[] = {
+ {SCULPT_FILTER_ORIENTATION_LOCAL,
+ "LOCAL",
+ 0,
+ "Local",
+ "Use the local axis to limit the displacement"},
+ {SCULPT_FILTER_ORIENTATION_WORLD,
+ "WORLD",
+ 0,
+ "World",
+ "Use the global axis to limit the displacement"},
+ {SCULPT_FILTER_ORIENTATION_VIEW,
+ "VIEW",
+ 0,
+ "View",
+ "Use the view axis to limit the displacement"},
+ {0, NULL, 0, NULL, NULL},
+};
+
static bool sculpt_mesh_filter_needs_pmap(int filter_type, bool use_face_sets)
{
return use_face_sets || ELEM(filter_type,
@@ -189,6 +265,7 @@ static bool sculpt_mesh_filter_needs_pmap(int filter_type, bool use_face_sets)
MESH_FILTER_RELAX,
MESH_FILTER_RELAX_FACE_SETS,
MESH_FILTER_SURFACE_SMOOTH,
+ MESH_FILTER_ENHANCE_DETAILS,
MESH_FILTER_SHARPEN);
}
@@ -306,7 +383,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
const uint *hash_co = (const uint *)orig_co;
const uint hash = BLI_hash_int_2d(hash_co[0], hash_co[1]) ^
BLI_hash_int_2d(hash_co[2], ss->filter_cache->random_seed);
- mul_v3_fl(normal, hash * (1.0f / 0xFFFFFFFF) - 0.5f);
+ mul_v3_fl(normal, hash * (1.0f / (float)0xFFFFFFFF) - 0.5f);
mul_v3_v3fl(disp, normal, fade);
break;
}
@@ -362,7 +439,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
if (ss->filter_cache->sharpen_intensify_detail_strength > 0.0f) {
float detail_strength[3];
normal_short_to_float_v3(detail_strength, orig_data.no);
- copy_v3_v3(detail_strength, ss->filter_cache->sharpen_detail_directions[vd.index]);
+ copy_v3_v3(detail_strength, ss->filter_cache->detail_directions[vd.index]);
madd_v3_v3fl(disp,
detail_strength,
-ss->filter_cache->sharpen_intensify_detail_strength *
@@ -370,13 +447,25 @@ static void mesh_filter_task_cb(void *__restrict userdata,
}
break;
}
+
+ case MESH_FILTER_ENHANCE_DETAILS: {
+ mul_v3_v3fl(disp, ss->filter_cache->detail_directions[vd.index], -fabsf(fade));
+ } break;
+ case MESH_FILTER_ERASE_DISPLACEMENT: {
+ fade = clamp_f(fade, 0.0f, 1.0f);
+ sub_v3_v3v3(disp, ss->filter_cache->limit_surface_co[vd.index], orig_co);
+ mul_v3_fl(disp, fade);
+ break;
+ }
}
+ SCULPT_filter_to_orientation_space(disp, ss->filter_cache);
for (int it = 0; it < 3; it++) {
if (!ss->filter_cache->enabled_axis[it]) {
disp[it] = 0.0f;
}
}
+ SCULPT_filter_to_object_space(disp, ss->filter_cache);
if (ELEM(filter_type, MESH_FILTER_SURFACE_SMOOTH, MESH_FILTER_SHARPEN)) {
madd_v3_v3v3fl(final_pos, vd.co, disp, clamp_f(fade, 0.0f, 1.0f));
@@ -394,14 +483,34 @@ static void mesh_filter_task_cb(void *__restrict userdata,
BKE_pbvh_node_mark_update(node);
}
+static void mesh_filter_enhance_details_init_directions(SculptSession *ss)
+{
+ const int totvert = SCULPT_vertex_count_get(ss);
+ for (int i = 0; i < totvert; i++) {
+ float avg[3];
+ SCULPT_neighbor_coords_average(ss, avg, i);
+ sub_v3_v3v3(ss->filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i));
+ }
+}
+
+static void mesh_filter_init_limit_surface_co(SculptSession *ss)
+{
+ const int totvert = SCULPT_vertex_count_get(ss);
+ ss->filter_cache->limit_surface_co = MEM_malloc_arrayN(
+ 3 * sizeof(float), totvert, "limit surface co");
+ for (int i = 0; i < totvert; i++) {
+ SCULPT_vertex_limit_surface_get(ss, i, ss->filter_cache->limit_surface_co[i]);
+ }
+}
+
static void mesh_filter_sharpen_init_factors(SculptSession *ss)
{
const int totvert = SCULPT_vertex_count_get(ss);
for (int i = 0; i < totvert; i++) {
float avg[3];
SCULPT_neighbor_coords_average(ss, avg, i);
- sub_v3_v3v3(ss->filter_cache->sharpen_detail_directions[i], avg, SCULPT_vertex_co_get(ss, i));
- ss->filter_cache->sharpen_factor[i] = len_v3(ss->filter_cache->sharpen_detail_directions[i]);
+ sub_v3_v3v3(ss->filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i));
+ ss->filter_cache->sharpen_factor[i] = len_v3(ss->filter_cache->detail_directions[i]);
}
float max_factor = 0.0f;
@@ -428,14 +537,14 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss)
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
- add_v3_v3(direction_avg, ss->filter_cache->sharpen_detail_directions[ni.index]);
+ add_v3_v3(direction_avg, ss->filter_cache->detail_directions[ni.index]);
sharpen_avg += ss->filter_cache->sharpen_factor[ni.index];
total++;
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
if (total > 0) {
- mul_v3_v3fl(ss->filter_cache->sharpen_detail_directions[i], direction_avg, 1.0f / total);
+ mul_v3_v3fl(ss->filter_cache->detail_directions[i], direction_avg, 1.0f / total);
ss->filter_cache->sharpen_factor[i] = sharpen_avg / total;
}
}
@@ -584,7 +693,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
SCULPT_boundary_info_ensure(ob);
}
- SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS);
+ SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS);
if (use_face_sets) {
ss->filter_cache->active_face_set = SCULPT_active_face_set_get(ss);
@@ -610,16 +719,29 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
op->ptr, "sharpen_curvature_smooth_iterations");
ss->filter_cache->sharpen_factor = MEM_mallocN(sizeof(float) * totvert, "sharpen factor");
- ss->filter_cache->sharpen_detail_directions = MEM_malloc_arrayN(
+ ss->filter_cache->detail_directions = MEM_malloc_arrayN(
totvert, sizeof(float[3]), "sharpen detail direction");
mesh_filter_sharpen_init_factors(ss);
}
+ if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_ENHANCE_DETAILS) {
+ ss->filter_cache->detail_directions = MEM_malloc_arrayN(
+ totvert, sizeof(float[3]), "detail direction");
+ mesh_filter_enhance_details_init_directions(ss);
+ }
+
+ if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_ERASE_DISPLACEMENT) {
+ mesh_filter_init_limit_surface_co(ss);
+ }
+
ss->filter_cache->enabled_axis[0] = deform_axis & MESH_FILTER_DEFORM_X;
ss->filter_cache->enabled_axis[1] = deform_axis & MESH_FILTER_DEFORM_Y;
ss->filter_cache->enabled_axis[2] = deform_axis & MESH_FILTER_DEFORM_Z;
+ SculptFilterOrientation orientation = RNA_enum_get(op->ptr, "orientation");
+ ss->filter_cache->orientation = orientation;
+
WM_event_add_modal_handler(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -653,6 +775,12 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
MESH_FILTER_DEFORM_X | MESH_FILTER_DEFORM_Y | MESH_FILTER_DEFORM_Z,
"Deform axis",
"Apply the deformation in the selected axis");
+ RNA_def_enum(ot->srna,
+ "orientation",
+ prop_mesh_filter_orientation_items,
+ SCULPT_FILTER_ORIENTATION_LOCAL,
+ "Orientation",
+ "Orientation of the axis to limit the filter displacement");
ot->prop = RNA_def_boolean(ot->srna,
"use_face_sets",
false,
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 22316eb4631..548ef00ad87 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -100,10 +100,16 @@ const float *SCULPT_vertex_color_get(SculptSession *ss, int index);
const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index);
void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]);
-/* Returs the info of the limit surface when Multires is available, otherwise it returns the
+/* Returns the info of the limit surface when Multires is available, otherwise it returns the
* current coordinate of the vertex. */
void SCULPT_vertex_limit_surface_get(SculptSession *ss, int index, float r_co[3]);
+/* Returns the pointer to the coordinates that should be edited from a brush tool iterator
+ * depending on the given deformation target. */
+float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss,
+ const int deform_target,
+ PBVHVertexIter *iter);
+
#define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256
typedef struct SculptVertexNeighborIter {
/* Storage */
@@ -337,7 +343,7 @@ float *SCULPT_boundary_automasking_init(Object *ob,
float *automask_factor);
/* Filters. */
-void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type);
+void SCULPT_filter_cache_init(struct bContext *C, Object *ob, Sculpt *sd, const int undo_type);
void SCULPT_filter_cache_free(SculptSession *ss);
void SCULPT_mask_filter_smooth_apply(
@@ -350,8 +356,33 @@ void SCULPT_do_cloth_brush(struct Sculpt *sd,
struct Object *ob,
struct PBVHNode **nodes,
int totnode);
+
void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim);
+struct SculptClothSimulation *SCULPT_cloth_brush_simulation_create(struct SculptSession *ss,
+ struct Brush *brush,
+ const float cloth_mass,
+ const float cloth_damping,
+ const bool use_collisions);
+void SCULPT_cloth_brush_simulation_init(struct SculptSession *ss,
+ struct SculptClothSimulation *cloth_sim);
+void SCULPT_cloth_brush_store_simulation_state(struct SculptSession *ss,
+ struct SculptClothSimulation *cloth_sim);
+
+void SCULPT_cloth_brush_do_simulation_step(struct Sculpt *sd,
+ struct Object *ob,
+ struct SculptClothSimulation *cloth_sim,
+ struct PBVHNode **nodes,
+ int totnode);
+
+void SCULPT_cloth_brush_build_nodes_constraints(struct Sculpt *sd,
+ struct Object *ob,
+ struct PBVHNode **nodes,
+ int totnode,
+ struct SculptClothSimulation *cloth_sim,
+ float initial_location[3],
+ const float radius);
+
void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
const struct Brush *brush,
const float location[3],
@@ -367,8 +398,12 @@ void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr,
BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush)
{
- return brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
- brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB;
+ return (brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
+ brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) ||
+ /* All brushes that are not the cloth brush deform the simulation using softbody
+ constriants instead of applying forces. */
+ (brush->sculpt_tool != SCULPT_TOOL_CLOTH &&
+ brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM);
}
/* Pose Brush. */
@@ -401,7 +436,7 @@ struct SculptBoundary *SCULPT_boundary_data_init(Object *object,
Brush *brush,
const int initial_vertex,
const float radius);
-void SCULPT_boundary_data_free(struct SculptBoundary *bdata);
+void SCULPT_boundary_data_free(struct SculptBoundary *boundary);
void SCULPT_do_boundary_brush(struct Sculpt *sd,
struct Object *ob,
struct PBVHNode **nodes,
@@ -865,6 +900,9 @@ typedef struct StrokeCache {
/* Pose brush */
struct SculptPoseIKChain *pose_ik_chain;
+ /* Enhance Details. */
+ float (*detail_directions)[3];
+
/* Clay Thumb brush */
/* Angle of the front tilting plane of the brush to simulate clay accumulation. */
float clay_thumb_front_angle;
@@ -880,7 +918,7 @@ typedef struct StrokeCache {
float true_initial_normal[3];
/* Boundary brush */
- struct SculptBoundary *bdata[PAINT_SYMM_AREAS];
+ struct SculptBoundary *boundaries[PAINT_SYMM_AREAS];
/* Surface Smooth Brush */
/* Stores the displacement produced by the laplacian step of HC smooth. */
@@ -920,8 +958,19 @@ typedef struct StrokeCache {
} StrokeCache;
+/* Sculpt Filters */
+typedef enum SculptFilterOrientation {
+ SCULPT_FILTER_ORIENTATION_LOCAL = 0,
+ SCULPT_FILTER_ORIENTATION_WORLD = 1,
+ SCULPT_FILTER_ORIENTATION_VIEW = 2,
+} SculptFilterOrientation;
+
+void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter_cache);
+void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cache);
+
typedef struct FilterCache {
bool enabled_axis[3];
+ bool enabled_force_axis[3];
int random_seed;
/* Used for alternating between filter operations in filters that need to apply different ones to
@@ -938,7 +987,17 @@ typedef struct FilterCache {
float sharpen_intensify_detail_strength;
int sharpen_curvature_smooth_iterations;
float *sharpen_factor;
- float (*sharpen_detail_directions)[3];
+ float (*detail_directions)[3];
+
+ /* Filter orientaiton. */
+ SculptFilterOrientation orientation;
+ float obmat[4][4];
+ float obmat_inv[4][4];
+ float viewmat[4][4];
+ float viewmat_inv[4][4];
+
+ /* Displacement eraser. */
+ float (*limit_surface_co)[3];
/* unmasked nodes */
PBVHNode **nodes;
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index 4d41d069155..e53e33c1186 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -165,6 +165,7 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata,
SculptSession *ss = data->ob->sculpt;
SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain;
SculptPoseIKChainSegment *segments = ik_chain->segments;
+ const Brush *brush = data->brush;
PBVHVertexIter vd;
float disp[3], new_co[3];
@@ -206,7 +207,9 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata,
/* Apply the accumulated displacement to the vertex. */
add_v3_v3v3(final_pos, orig_data.co, total_disp);
- copy_v3_v3(vd.co, final_pos);
+
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ copy_v3_v3(target_co, final_pos);
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index 2b93298ac4a..63fe8643628 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -195,6 +195,85 @@ void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index
}
}
+static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ Sculpt *sd = data->sd;
+ const Brush *brush = data->brush;
+
+ PBVHVertexIter vd;
+
+ float bstrength = ss->cache->bstrength;
+ CLAMP(bstrength, -1.0f, 1.0f);
+
+ SculptBrushTest test;
+ SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
+ ss, &test, data->brush->falloff_shape);
+
+ const int thread_id = BLI_task_parallel_thread_id(tls);
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ if (sculpt_brush_test_sq_fn(&test, vd.co)) {
+ const float fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+
+ float disp[3];
+ madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade);
+ SCULPT_clip(sd, ss, vd.co, disp);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+static void SCULPT_enhance_details_brush(Sculpt *sd,
+ Object *ob,
+ PBVHNode **nodes,
+ const int totnode)
+{
+ SculptSession *ss = ob->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+
+ SCULPT_vertex_random_access_ensure(ss);
+ SCULPT_boundary_info_ensure(ob);
+
+ if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
+ const int totvert = SCULPT_vertex_count_get(ss);
+ ss->cache->detail_directions = MEM_malloc_arrayN(
+ totvert, 3 * sizeof(float), "details directions");
+
+ for (int i = 0; i < totvert; i++) {
+ float avg[3];
+ SCULPT_neighbor_coords_average(ss, avg, i);
+ sub_v3_v3v3(ss->cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i));
+ }
+ }
+
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ };
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &data, do_enhance_details_brush_task_cb_ex, &settings);
+}
+
static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
@@ -300,7 +379,14 @@ void SCULPT_smooth(Sculpt *sd,
void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
{
SculptSession *ss = ob->sculpt;
- SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false);
+ if (ss->cache->bstrength <= 0.0f) {
+ /* Invert mode, intensify details. */
+ SCULPT_enhance_details_brush(sd, ob, nodes, totnode);
+ }
+ else {
+ /* Regular mode, smooth. */
+ SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false);
+ }
}
/* HC Smooth Algorithm. */
diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c
index 4c54a0465b9..bdada4d2565 100644
--- a/source/blender/editors/sculpt_paint/sculpt_transform.c
+++ b/source/blender/editors/sculpt_paint/sculpt_transform.c
@@ -76,7 +76,7 @@ void ED_sculpt_init_transform(struct bContext *C)
ss->pivot_rot[3] = 1.0f;
SCULPT_vertex_random_access_ensure(ss);
- SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS);
+ SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS);
}
static void sculpt_transform_task_cb(void *__restrict userdata,
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 050dca07c34..e8eddc014db 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -306,7 +306,6 @@ static void SOUND_OT_update_animation_flags(wmOperatorType *ot)
static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op))
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
/* NOTE: We will be forcefully evaluating dependency graph at every frame, so no need to ensure
* current scene state is evaluated as it will be lost anyway. */
@@ -318,11 +317,11 @@ static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op))
for (cfra = (scene->r.sfra > 0) ? (scene->r.sfra - 1) : 0; cfra <= scene->r.efra + 1; cfra++) {
scene->r.cfra = cfra;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
scene->r.cfra = oldfra;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index ada4243ab4e..8634e5a5f29 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -169,7 +169,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* first backdrop strips */
float ymax = ACHANNEL_FIRST_TOP(ac);
@@ -276,7 +276,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region
}
}
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* black line marking 'current frame' for Time-Slide transform mode */
if (saction->flag & SACTION_MOVING) {
@@ -558,7 +558,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* Iterate over pointcaches on the active object, and draw each one's range. */
float y_offset = 0.0f;
@@ -577,7 +577,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
y_offset += cache_draw_height;
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();
BLI_freelistN(&pidlist);
diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt
index 25ff6bbd098..75d91174470 100644
--- a/source/blender/editors/space_buttons/CMakeLists.txt
+++ b/source/blender/editors/space_buttons/CMakeLists.txt
@@ -54,4 +54,9 @@ if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
endif()
+if(WITH_EXPERIMENTAL_FEATURES)
+ add_definitions(-DWITH_PARTICLE_NODES)
+ add_definitions(-DWITH_HAIR_NODES)
+endif()
+
blender_add_lib(bf_editor_space_buttons "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 5885d3dcbb0..3976e18d70c 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -249,12 +249,16 @@ static bool buttons_context_path_data(ButsContextPath *path, int type)
if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) {
return true;
}
+#ifdef WITH_HAIR_NODES
if (RNA_struct_is_a(ptr->type, &RNA_Hair) && (type == -1 || type == OB_HAIR)) {
return true;
}
+#endif
+#ifdef WITH_PARTICLE_NODES
if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (type == -1 || type == OB_POINTCLOUD)) {
return true;
}
+#endif
if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (type == -1 || type == OB_VOLUME)) {
return true;
}
@@ -871,14 +875,18 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
set_pointer_type(path, result, &RNA_LightProbe);
return 1;
}
+#ifdef WITH_HAIR_NODES
if (CTX_data_equals(member, "hair")) {
set_pointer_type(path, result, &RNA_Hair);
return 1;
}
+#endif
+#ifdef WITH_PARTICLE_NODES
if (CTX_data_equals(member, "pointcloud")) {
set_pointer_type(path, result, &RNA_PointCloud);
return 1;
}
+#endif
if (CTX_data_equals(member, "volume")) {
set_pointer_type(path, result, &RNA_Volume);
return 1;
diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c
index c7328ae9f8f..8aaf3faffec 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_draw.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c
@@ -142,7 +142,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *region, Scene *scene)
strip[3] = 0.5f;
selected_strip[3] = 1.0f;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
clip_draw_dopesheet_background(region, clip, pos_id);
@@ -288,7 +288,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *region, Scene *scene)
immUnbindProgram();
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
@@ -389,7 +389,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *region)
PropertyRNA *chan_prop_lock = RNA_struct_type_find_property(&RNA_MovieTrackingTrack, "lock");
BLI_assert(chan_prop_lock);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
for (channel = dopesheet->channels.first; channel; channel = channel->next) {
float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);
@@ -426,7 +426,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *region)
/* adjust y-position for next one */
y -= CHANNEL_STEP;
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
UI_block_end(C, block);
UI_block_draw(C, block);
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 07bdd337269..17539b2c423 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -153,9 +153,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *region, MovieClip *clip
MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking);
MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
/* cache background */
ED_region_cache_draw_background(region);
@@ -245,7 +243,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *region, MovieClip *clip
}
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* current frame */
x = (sc->user.framenr - sfra) / (efra - sfra + 1) * region->winx;
@@ -330,9 +328,7 @@ static void draw_movieclip_buffer(const bContext *C,
/* checkerboard for case alpha */
if (ibuf->planes == 32) {
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
imm_draw_box_checker_2d(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y);
}
@@ -346,7 +342,7 @@ static void draw_movieclip_buffer(const bContext *C,
ED_draw_imbuf_ctx(C, ibuf, x, y, use_filter, zoomx * width / ibuf->x, zoomy * height / ibuf->y);
if (ibuf->planes == 32) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
if (sc->flag & SC_SHOW_METADATA) {
@@ -1212,9 +1208,7 @@ static void draw_plane_marker_image(Scene *scene,
if (plane_track->image_opacity != 1.0f || ibuf->planes == 32) {
transparent = true;
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
}
GPUTexture *texture = GPU_texture_create_nD(ibuf->x,
@@ -1266,7 +1260,7 @@ static void draw_plane_marker_image(Scene *scene,
GPU_texture_free(texture);
if (transparent) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c
index 277930495bd..4cf3e3e0798 100644
--- a/source/blender/editors/space_clip/clip_graph_draw.c
+++ b/source/blender/editors/space_clip/clip_graph_draw.c
@@ -192,7 +192,7 @@ static void draw_tracks_motion_and_error_curves(View2D *v2d, SpaceClip *sc, uint
}
/* Draw graph lines. */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
clip_graph_tracking_values_iterate(sc,
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
(sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
@@ -200,7 +200,7 @@ static void draw_tracks_motion_and_error_curves(View2D *v2d, SpaceClip *sc, uint
tracking_segment_point_cb,
tracking_segment_start_cb,
tracking_segment_end_cb);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* Selected knot handles on top of curves. */
if (draw_knots) {
diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c
index 03f791ad70d..bcbf843f51c 100644
--- a/source/blender/editors/space_clip/clip_utils.c
+++ b/source/blender/editors/space_clip/clip_utils.c
@@ -415,9 +415,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene)
UI_view2d_view_ortho(v2d);
/* currently clip editor supposes that editing clip length is equal to scene frame range */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -426,7 +424,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene)
immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax);
immRectf(pos, (float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUniformThemeColorShade(TH_BACK, -60);
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 083d41747b3..51e6c99ff39 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -267,7 +267,7 @@ static void file_draw_preview(uiBlock *block,
xco = sx + (int)dx;
yco = sy - layout->prv_h + (int)dy;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* the large image */
@@ -290,8 +290,7 @@ static void file_draw_preview(uiBlock *block,
if (!is_icon && typeflags & FILE_TYPE_BLENDERLIB) {
/* Datablock preview images use premultiplied alpha. */
- GPU_blend_set_func_separate(
- GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA_PREMULT);
}
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
@@ -309,8 +308,7 @@ static void file_draw_preview(uiBlock *block,
1.0f,
col);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
if (icon && is_icon) {
/* Small icon in the middle of large image, scaled to fit container and UI scale */
@@ -391,7 +389,7 @@ static void file_draw_preview(uiBlock *block,
UI_but_drag_set_image(but, BLI_strdup(path), icon, imb, scale, true);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index f5861e792bc..ac860b72e84 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -290,7 +290,7 @@ static void draw_fcurve_vertices(ARegion *region,
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_program_point_size(true);
/* draw the two handles first (if they're shown, the curve doesn't
@@ -303,7 +303,7 @@ static void draw_fcurve_vertices(ARegion *region,
draw_fcurve_keyframe_vertices(fcu, v2d, !(fcu->flag & FCURVE_PROTECTED), pos);
GPU_program_point_size(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* Handles ---------------- */
@@ -344,7 +344,7 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu)
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
GPU_line_smooth(true);
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immBeginAtMost(GPU_PRIM_LINES, 4 * 2 * fcu->totvert);
@@ -421,7 +421,7 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu)
immEnd();
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
GPU_line_smooth(false);
}
@@ -474,7 +474,7 @@ static void draw_fcurve_samples(SpaceGraph *sipo, ARegion *region, FCurve *fcu)
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
GPU_line_smooth(true);
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -486,7 +486,7 @@ static void draw_fcurve_samples(SpaceGraph *sipo, ARegion *region, FCurve *fcu)
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
GPU_line_smooth(false);
}
@@ -1002,7 +1002,7 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
GPU_line_smooth(true);
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
const uint shdr_pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -1034,7 +1034,7 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
GPU_line_smooth(false);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* This is called twice from space_graph.c -> graph_main_region_draw()
@@ -1088,7 +1088,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, shor
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
GPU_line_smooth(true);
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
const uint shdr_pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -1149,7 +1149,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, shor
if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
GPU_line_smooth(false);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* 2) draw handles and vertices as appropriate based on active
@@ -1262,9 +1262,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region)
float ymax = ACHANNEL_FIRST_TOP(ac);
/* set blending again, as may not be set in previous step */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac), channel_index++) {
float ymin = ymax - ACHANNEL_HEIGHT(ac);
@@ -1282,7 +1280,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region)
UI_block_end(C, block);
UI_block_draw(C, block);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* free tempolary channels */
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index a4f76384cc6..4e0f60544e6 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -249,7 +249,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
/* Draw a green line to indicate the cursor value */
immUniformThemeColorShadeAlpha(TH_CFRAME, -10, -50);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_width(2.0);
immBegin(GPU_PRIM_LINES, 2);
@@ -257,7 +257,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
immVertex2f(pos, v2d->cur.xmax, y);
immEnd();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* current frame or vertical component of vertical component of the cursor */
@@ -268,7 +268,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
/* to help differentiate this from the current frame,
* draw slightly darker like the horizontal one */
immUniformThemeColorShadeAlpha(TH_CFRAME, -40, -50);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_width(2.0);
immBegin(GPU_PRIM_LINES, 2);
@@ -276,7 +276,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region)
immVertex2f(pos, x, v2d->cur.ymax);
immEnd();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
immUnbindProgram();
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index f70589ac5f1..d58f5ede7d7 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -175,9 +175,7 @@ void ED_image_draw_info(Scene *scene,
float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0;
float col[4], finalcol[4];
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
@@ -189,7 +187,7 @@ void ED_image_draw_info(Scene *scene,
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
BLF_size(blf_mono_font, 11 * U.pixelsize, U.dpi);
@@ -350,7 +348,7 @@ void ED_image_draw_info(Scene *scene,
copy_v4_v4(finalcol, col);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
dx += 0.25f * UI_UNIT_X;
BLI_rcti_init(&color_rect,
@@ -389,10 +387,10 @@ void ED_image_draw_info(Scene *scene,
immRecti(pos, color_quater_x, color_quater_y, color_rect_half.xmax, color_rect_half.ymax);
immRecti(pos, color_rect_half.xmin, color_rect_half.ymin, color_quater_x, color_quater_y);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformColor3fvAlpha(finalcol, fp ? fp[3] : (cp[3] / 255.0f));
immRecti(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
else {
immUniformColor3fv(finalcol);
@@ -540,9 +538,7 @@ static void draw_udim_label(ARegion *region, float fx, float fy, const char *lab
int x, y;
UI_view2d_view_to_region(&region->v2d, fx, fy, &x, &y);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
int textwidth = BLF_width(blf_mono_font, label, strlen(label)) + 10;
float stepx = BLI_rcti_size_x(&region->v2d.mask) / BLI_rctf_size_x(&region->v2d.cur);
@@ -560,7 +556,7 @@ static void draw_udim_label(ARegion *region, float fx, float fy, const char *lab
BLF_position(blf_mono_font, (int)(x + 10), (int)(y + 10), 0);
BLF_draw_ascii(blf_mono_font, label, strlen(label));
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void draw_image_buffer(const bContext *C,
@@ -602,9 +598,7 @@ static void draw_image_buffer(const bContext *C,
if (sima_flag & SI_USE_ALPHA) {
imm_draw_box_checker_2d(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
}
/* If RGBA display with color management */
@@ -662,7 +656,7 @@ static void draw_image_buffer(const bContext *C,
}
if (sima_flag & SI_USE_ALPHA) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
@@ -771,15 +765,13 @@ static void draw_image_paint_helpers(
return;
}
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
immDrawPixelsTex(
&state, x, y, ibuf->x, ibuf->y, GPU_RGBA8, false, display_buffer, zoomx, zoomy, col);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
BKE_image_release_ibuf(brush->clone.image, ibuf, NULL);
IMB_display_buffer_release(cache_handle);
@@ -1058,9 +1050,7 @@ void draw_image_cache(const bContext *C, ARegion *region)
const rcti *rect_visible = ED_region_visible_rect(region);
const int region_bottom = rect_visible->ymin;
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
/* Draw cache background. */
ED_region_cache_draw_background(region);
@@ -1076,7 +1066,7 @@ void draw_image_cache(const bContext *C, ARegion *region)
region, num_segments, points, sfra + sima->iuser.offset, efra + sima->iuser.offset);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* Draw current frame. */
x = (cfra - sfra) / (efra - sfra + 1) * region->winx;
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 4e91da01cc9..e97031736ca 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -547,19 +547,20 @@ static void get_stats_string(
info + *ofs, len - *ofs, TIP_(" | Objects:%s/%s"), stats_fmt->totobjsel, stats_fmt->totobj);
}
-const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C)
+static const char *info_statusbar_string(Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer,
+ char statusbar_flag)
{
char formatted_mem[15];
size_t ofs = 0;
- char *info = screen->statusbar_info;
- int len = sizeof(screen->statusbar_info);
+ static char info[256];
+ int len = sizeof(info);
info[0] = '\0';
/* Scene statistics. */
- if (U.statusbar_flag & STATUSBAR_SHOW_STATS) {
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Scene *scene = CTX_data_scene(C);
+ if (statusbar_flag & STATUSBAR_SHOW_STATS) {
SceneStatsFmt stats_fmt;
if (format_stats(bmain, scene, view_layer, &stats_fmt)) {
get_stats_string(info + ofs, len, &ofs, view_layer, &stats_fmt);
@@ -567,7 +568,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C)
}
/* Memory status. */
- if (U.statusbar_flag & STATUSBAR_SHOW_MEMORY) {
+ if (statusbar_flag & STATUSBAR_SHOW_MEMORY) {
if (info[0]) {
ofs += BLI_snprintf(info + ofs, len - ofs, " | ");
}
@@ -577,7 +578,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C)
}
/* GPU VRAM status. */
- if ((U.statusbar_flag & STATUSBAR_SHOW_VRAM) && (GPU_mem_stats_supported())) {
+ if ((statusbar_flag & STATUSBAR_SHOW_VRAM) && (GPU_mem_stats_supported())) {
int gpu_free_mem_kb, gpu_tot_mem_kb;
GPU_mem_stats_get(&gpu_tot_mem_kb, &gpu_free_mem_kb);
float gpu_total_gb = gpu_tot_mem_kb / 1048576.0f;
@@ -599,7 +600,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C)
}
/* Blender version. */
- if (U.statusbar_flag & STATUSBAR_SHOW_VERSION) {
+ if (statusbar_flag & STATUSBAR_SHOW_VERSION) {
if (info[0]) {
ofs += BLI_snprintf(info + ofs, len - ofs, " | ");
}
@@ -609,6 +610,20 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C)
return info;
}
+const char *ED_info_statusbar_string(Main *bmain, Scene *scene, ViewLayer *view_layer)
+{
+ return info_statusbar_string(bmain, scene, view_layer, U.statusbar_flag);
+}
+
+const char *ED_info_statistics_string(Main *bmain, Scene *scene, ViewLayer *view_layer)
+{
+ const eUserpref_StatusBar_Flag statistics_status_bar_flag = STATUSBAR_SHOW_STATS |
+ STATUSBAR_SHOW_MEMORY |
+ STATUSBAR_SHOW_VERSION;
+
+ return info_statusbar_string(bmain, scene, view_layer, statistics_status_bar_flag);
+}
+
static void stats_row(int col1,
const char *key,
int col2,
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 93a79d9a2bc..4d9a4fb2706 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -84,9 +84,7 @@ static void textview_draw_sel(const char *str,
const int sta = BLI_str_utf8_offset_to_column(str, max_ii(sel[0], 0));
const int end = BLI_str_utf8_offset_to_column(str, min_ii(sel[1], str_len_draw));
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
@@ -97,7 +95,7 @@ static void textview_draw_sel(const char *str,
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
@@ -240,7 +238,7 @@ static bool textview_draw_string(TextViewDrawState *tds,
int vpadding = (tds->lheight + (tds->row_vpadding * 2) - UI_DPI_ICON_SIZE) / 2;
int hpadding = tds->draw_rect->xmin - (UI_DPI_ICON_SIZE * 1.3f);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_icon_draw_ex(hpadding,
line_top - UI_DPI_ICON_SIZE - vpadding,
icon,
@@ -249,7 +247,7 @@ static bool textview_draw_string(TextViewDrawState *tds,
0.0f,
icon_fg,
false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
tds->xy[1] += tds->row_vpadding;
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 97939a93d01..b0d5360e29b 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -321,7 +321,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uin
/* draw with AA'd line */
GPU_line_smooth(true);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* influence -------------------------- */
if (strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) {
@@ -374,7 +374,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uin
/* turn off AA'd lines */
GPU_line_smooth(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* helper call to setup dashed-lines for strip outlines */
@@ -434,9 +434,7 @@ static void nla_draw_strip(SpaceNla *snla,
*/
if ((strip->extendmode != NLASTRIP_EXTEND_NOTHING) && (non_solo == 0)) {
/* enable transparency... */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
switch (strip->extendmode) {
/* since this does both sides,
@@ -468,7 +466,7 @@ static void nla_draw_strip(SpaceNla *snla,
break;
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* draw 'inside' of strip itself */
@@ -487,9 +485,9 @@ static void nla_draw_strip(SpaceNla *snla,
/* strip is in disabled track - make less visible */
immUniformColor3fvAlpha(color, 0.1f);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immRectf(shdr_pos, strip->start, yminc, strip->end, ymaxc);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* draw strip's control 'curves'
@@ -746,9 +744,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region)
/* just draw a semi-shaded rect spanning the width of the viewable area if there's data,
* and a second darker rect within which we draw keyframe indicator dots if there's data
*/
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* get colors for drawing */
float color[4];
@@ -790,7 +786,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region)
nla_action_draw_keyframes(
v2d, adt, ale->data, ycenter, ymin + NLACHANNEL_SKIP, ymax - NLACHANNEL_SKIP);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
break;
}
}
@@ -854,9 +850,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *region)
float ymax = NLACHANNEL_FIRST_TOP(ac);
/* set blending again, as may not be set in previous step */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* loop through channels, and set up drawing depending on their type */
for (ale = anim_data.first; ale;
@@ -876,7 +870,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *region)
UI_block_end(C, block);
UI_block_draw(C, block);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* free temporary channels */
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 37daa881317..fcc02f49d07 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -602,7 +602,7 @@ static void node_draw_reroute(const bContext *C,
/* outline active and selected emphasis */
if (node->flag & SELECT) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
/* using different shades of TH_TEXT_HI for the empasis, like triangle */
if (node->flag & NODE_ACTIVE) {
@@ -614,7 +614,7 @@ static void node_draw_reroute(const bContext *C,
UI_draw_roundbox_4fv(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size, debug_color);
GPU_line_smooth(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
#endif
@@ -3688,13 +3688,11 @@ void draw_nodespace_back_pix(const bContext *C,
GPU_shader_unbind();
}
else if (snode->flag & SNODE_USE_ALPHA) {
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
else {
ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom);
@@ -4013,7 +4011,7 @@ static void nodelink_batch_draw(SpaceNode *snode)
return;
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
float colors[6][4] = {{0.0f}};
UI_GetThemeColor4fv(TH_WIRE_INNER, colors[nodelink_get_color_id(TH_WIRE_INNER)]);
@@ -4026,14 +4024,14 @@ static void nodelink_batch_draw(SpaceNode *snode)
GPU_vertbuf_use(g_batch_link.inst_vbo); /* force update. */
GPU_batch_program_set_builtin(g_batch_link.batch, GPU_SHADER_2D_NODELINK_INST);
- GPU_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, (float *)colors);
+ GPU_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, colors);
GPU_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->aspect * LINK_WIDTH);
GPU_batch_uniform_1f(g_batch_link.batch, "arrowSize", ARROW_SIZE);
GPU_batch_draw(g_batch_link.batch);
nodelink_batch_reset();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
void nodelink_batch_start(SpaceNode *UNUSED(snode))
@@ -4108,8 +4106,8 @@ void node_draw_link_bezier(
GPUBatch *batch = g_batch_link.batch_single;
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK);
- GPU_batch_uniform_2fv_array(batch, "bezierPts", 4, (float *)vec);
- GPU_batch_uniform_4fv_array(batch, "colors", 3, (float *)colors);
+ GPU_batch_uniform_2fv_array(batch, "bezierPts", 4, vec);
+ GPU_batch_uniform_4fv_array(batch, "colors", 3, colors);
GPU_batch_uniform_1f(batch, "expandSize", snode->aspect * LINK_WIDTH);
GPU_batch_uniform_1f(batch, "arrowSize", ARROW_SIZE);
GPU_batch_uniform_1i(batch, "doArrow", drawarrow);
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 3fd0b0a5a58..814473b0e9a 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -52,6 +52,7 @@
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
+#include "GPU_viewport.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -690,13 +691,13 @@ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node)
{
bNodeLink *link;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
for (link = node->internal_links.first; link; link = link->next) {
node_draw_link_bezier(v2d, snode, link, TH_REDALERT, TH_REDALERT, -1);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* flags used in gpu_shader_keyframe_diamond_frag.glsl */
@@ -834,8 +835,8 @@ void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[
uint outline_col_id = GPU_vertformat_attr_add(
format, "outlineColor", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- gpuPushAttr(GPU_BLEND_BIT);
- GPU_blend(true);
+ eGPUBlend state = GPU_blend_get();
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
@@ -859,53 +860,27 @@ void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[
immUnbindProgram();
GPU_program_point_size(false);
- gpuPopAttr();
+
+ /* Restore. */
+ GPU_blend(state);
}
/* ************** Socket callbacks *********** */
-static void node_draw_preview_background(float tile, rctf *rect)
+static void node_draw_preview_background(rctf *rect)
{
- float x, y;
-
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_CHECKER);
- /* draw checkerboard backdrop to show alpha */
- immUniformColor3ub(120, 120, 120);
+ /* Drawing the checkerboard. */
+ const float checker_dark = UI_ALPHA_CHECKER_DARK / 255.0f;
+ const float checker_light = UI_ALPHA_CHECKER_LIGHT / 255.0f;
+ immUniform4f("color1", checker_dark, checker_dark, checker_dark, 1.0f);
+ immUniform4f("color2", checker_light, checker_light, checker_light, 1.0f);
+ immUniform1i("size", 8);
immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
- immUniformColor3ub(160, 160, 160);
-
- for (y = rect->ymin; y < rect->ymax; y += tile * 2) {
- for (x = rect->xmin; x < rect->xmax; x += tile * 2) {
- float tilex = tile, tiley = tile;
-
- if (x + tile > rect->xmax) {
- tilex = rect->xmax - x;
- }
- if (y + tile > rect->ymax) {
- tiley = rect->ymax - y;
- }
-
- immRectf(pos, x, y, x + tilex, y + tiley);
- }
- }
- for (y = rect->ymin + tile; y < rect->ymax; y += tile * 2) {
- for (x = rect->xmin + tile; x < rect->xmax; x += tile * 2) {
- float tilex = tile, tiley = tile;
-
- if (x + tile > rect->xmax) {
- tilex = rect->xmax - x;
- }
- if (y + tile > rect->ymax) {
- tiley = rect->ymax - y;
- }
-
- immRectf(pos, x, y, x + tilex, y + tiley);
- }
- }
immUnbindProgram();
}
@@ -934,12 +909,11 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
scale = yscale;
}
- node_draw_preview_background(BLI_rctf_size_x(prv) / 10.0f, &draw_rect);
+ node_draw_preview_background(&draw_rect);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* premul graphics */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
immDrawPixelsTex(&state,
@@ -954,7 +928,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
scale,
NULL);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -978,23 +952,8 @@ static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_
void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha)
{
rctf *rct = &node->totr;
-
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- if (node->parent == NULL) {
- ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT);
- }
- else {
- const float margin = 3.0f;
-
- const float color[4] = {0.0f, 0.0f, 0.0f, 0.33f};
- UI_draw_roundbox_aa(true,
- rct->xmin - margin,
- rct->ymin - margin,
- rct->xmax + margin,
- rct->ymax + margin,
- radius + margin,
- color);
- }
+ ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT);
}
void node_draw_sockets(View2D *v2d,
@@ -1024,7 +983,7 @@ void node_draw_sockets(View2D *v2d,
uint outline_col_id = GPU_vertformat_attr_add(
format, "outlineColor", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
immUniform1f("outline_scale", 0.7f);
@@ -1158,7 +1117,7 @@ void node_draw_sockets(View2D *v2d,
immUnbindProgram();
GPU_program_point_size(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void node_draw_basis(const bContext *C,
@@ -1434,7 +1393,7 @@ static void node_draw_hidden(const bContext *C,
/* custom color inline */
if (node->flag & NODE_CUSTOM_COLOR) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
UI_draw_roundbox_3fv_alpha(false,
@@ -1447,7 +1406,7 @@ static void node_draw_hidden(const bContext *C,
1.0f);
GPU_line_smooth(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* title */
@@ -1681,7 +1640,7 @@ void node_draw_nodetree(const bContext *C,
}
/* node lines */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
nodelink_batch_start(snode);
for (link = ntree->links.first; link; link = link->next) {
if (!nodeLinkIsHidden(link)) {
@@ -1689,7 +1648,7 @@ void node_draw_nodetree(const bContext *C,
}
}
nodelink_batch_end(snode);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* draw foreground nodes, last nodes in front */
for (a = 0, node = ntree->nodes.first; node; node = node->next, a++) {
@@ -1750,12 +1709,12 @@ static void draw_group_overlay(const bContext *C, ARegion *region)
float color[4];
/* shade node groups to separate them visually */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_GetThemeColorShadeAlpha4fv(TH_NODE_GROUP, 0, 0, color);
UI_draw_roundbox_corner_set(UI_CNR_NONE);
UI_draw_roundbox_4fv(true, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0, color);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* set the block bounds to clip mouse events from underlying nodes */
block = UI_block_begin(C, region, "node tree bounds block", UI_EMBOSS);
@@ -1770,10 +1729,16 @@ void drawnodespace(const bContext *C, ARegion *region)
SpaceNode *snode = CTX_wm_space_node(C);
View2D *v2d = &region->v2d;
- UI_ThemeClearColor(TH_BACK);
- GPU_clear(GPU_COLOR_BIT);
+ /* Setup offscreen buffers. */
+ GPUViewport *viewport = WM_draw_region_get_viewport(region);
+
+ GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
+ GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
UI_view2d_view_ortho(v2d);
+ UI_ThemeClearColor(TH_BACK);
+ GPU_clear(GPU_COLOR_BIT);
+ GPU_depth_test(false);
/* XXX snode->cursor set in coordspace for placing new nodes, used for drawing noodles too */
UI_view2d_region_to_view(&region->v2d,
@@ -1789,8 +1754,7 @@ void drawnodespace(const bContext *C, ARegion *region)
ED_region_draw_cb_draw(C, region, REGION_DRAW_PRE_VIEW);
/* only set once */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
/* nodes */
snode_set_context(C);
@@ -1876,7 +1840,7 @@ void drawnodespace(const bContext *C, ARegion *region)
}
/* temporary links */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
for (nldrag = snode->linkdrag.first; nldrag; nldrag = nldrag->next) {
for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) {
@@ -1884,7 +1848,7 @@ void drawnodespace(const bContext *C, ARegion *region)
}
}
GPU_line_smooth(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
if (snode->flag & SNODE_SHOW_GPENCIL) {
/* draw grease-pencil ('canvas' strokes) */
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index c88b6a1b297..ef931dd9bb8 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -207,12 +207,11 @@ static void compo_initjob(void *cjv)
ViewLayer *view_layer = cj->view_layer;
cj->compositor_depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
- DEG_graph_build_for_compositor_preview(
- cj->compositor_depsgraph, bmain, scene, view_layer, cj->ntree);
+ DEG_graph_build_for_compositor_preview(cj->compositor_depsgraph, cj->ntree);
/* NOTE: Don't update animation to preserve unkeyed changes, this means can not use
* evaluate_on_framechange. */
- DEG_evaluate_on_refresh(bmain, cj->compositor_depsgraph);
+ DEG_evaluate_on_refresh(cj->compositor_depsgraph);
bNodeTree *ntree_eval = (bNodeTree *)DEG_get_evaluated_id(cj->compositor_depsgraph,
&cj->ntree->id);
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 28e233b6dd2..1705b9dd606 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -2729,7 +2729,7 @@ static void outliner_draw_iconrow_number(const uiFontStyle *fstyle,
number_text,
text_col);
UI_fontstyle_set(fstyle);
- GPU_blend(true); /* Roundbox and text drawing disables. */
+ GPU_blend(GPU_BLEND_ALPHA); /* Roundbox and text drawing disables. */
}
static void outliner_icon_background_colors(float icon_color[4], float icon_border[4])
@@ -2780,7 +2780,7 @@ static void outliner_draw_iconrow_doit(uiBlock *block,
(float)ys + UI_UNIT_Y - ufac,
(float)UI_UNIT_Y / 4.0f,
icon_border);
- GPU_blend(true); /* Roundbox disables. */
+ GPU_blend(GPU_BLEND_ALPHA); /* Roundbox disables. */
}
if (tselem->flag & TSE_HIGHLIGHTED) {
@@ -2981,7 +2981,7 @@ static void outliner_draw_tree_element(bContext *C,
xmax -= restrict_column_width + UI_UNIT_X;
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* colors for active/selected data */
if (tselem->type == 0) {
@@ -3068,7 +3068,7 @@ static void outliner_draw_tree_element(bContext *C,
(float)*starty + UI_UNIT_Y - ufac,
UI_UNIT_Y / 4.0f,
icon_border);
- GPU_blend(true); /* roundbox disables it */
+ GPU_blend(GPU_BLEND_ALPHA); /* roundbox disables it */
te->flag |= TE_ACTIVE; /* For lookup in display hierarchies. */
}
@@ -3116,7 +3116,7 @@ static void outliner_draw_tree_element(bContext *C,
offsx += UI_UNIT_X + 4 * ufac;
}
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* name */
if ((tselem->flag & TSE_TEXTBUT) == 0) {
@@ -3140,7 +3140,7 @@ static void outliner_draw_tree_element(bContext *C,
else if (tselem->type != TSE_R_LAYER) {
int tempx = startx + offsx;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
MergedIconRow merged = {{0}};
outliner_draw_iconrow(C,
@@ -3156,7 +3156,7 @@ static void outliner_draw_tree_element(bContext *C,
alpha_fac,
&merged);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
}
@@ -3315,9 +3315,9 @@ static void outliner_draw_hierarchy_lines(SpaceOutliner *space_outliner,
UI_GetThemeColorBlend3ubv(TH_BACK, TH_TEXT, 0.4f, col);
col[3] = 255;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
outliner_draw_hierarchy_lines_recursive(pos, space_outliner, lb, startx, col, false, starty);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();
}
@@ -3464,7 +3464,7 @@ static void outliner_draw_highlights(ARegion *region,
UI_GetThemeColor4fv(TH_MATCH, col_searchmatch);
col_searchmatch[3] = 0.5f;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -3479,7 +3479,7 @@ static void outliner_draw_highlights(ARegion *region,
startx,
starty);
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void outliner_draw_tree(bContext *C,
@@ -3493,8 +3493,7 @@ static void outliner_draw_tree(bContext *C,
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
int starty, startx;
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); /* Only once. */
+ GPU_blend(GPU_BLEND_ALPHA); /* Only once. */
if (space_outliner->outlinevis == SO_DATA_API) {
/* struct marks */
@@ -3508,12 +3507,12 @@ static void outliner_draw_tree(bContext *C,
outliner_draw_highlights(region, space_outliner, startx, &starty);
/* set scissor so tree elements or lines can't overlap restriction icons */
- float scissor[4] = {0};
+ int scissor[4] = {0};
if (restrict_column_width > 0.0f) {
int mask_x = BLI_rcti_size_x(&region->v2d.mask) - (int)restrict_column_width + 1;
CLAMP_MIN(mask_x, 0);
- GPU_scissor_get_f(scissor);
+ GPU_scissor_get(scissor);
GPU_scissor(0, 0, mask_x, region->winy);
}
diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c
index e9ed1cec228..f739bfe367e 100644
--- a/source/blender/editors/space_script/script_edit.c
+++ b/source/blender/editors/space_script/script_edit.c
@@ -42,7 +42,7 @@
#include "script_intern.h" // own include
#ifdef WITH_PYTHON
-# include "BPY_extern.h" /* BPY_script_exec */
+# include "BPY_extern_run.h"
#endif
static int run_pyfile_exec(bContext *C, wmOperator *op)
@@ -50,7 +50,7 @@ static int run_pyfile_exec(bContext *C, wmOperator *op)
char path[512];
RNA_string_get(op->ptr, "filepath", path);
#ifdef WITH_PYTHON
- if (BPY_execute_filepath(C, path, op->reports)) {
+ if (BPY_run_filepath(C, path, op->reports)) {
ARegion *region = CTX_wm_region(C);
ED_region_tag_redraw(region);
return OPERATOR_FINISHED;
@@ -120,7 +120,7 @@ static int script_reload_exec(bContext *C, wmOperator *op)
/* TODO, this crashes on netrender and keying sets, need to look into why
* disable for now unless running in debug mode */
WM_cursor_wait(1);
- BPY_execute_string(
+ BPY_run_string_eval(
C, (const char *[]){"bpy", NULL}, "bpy.utils.load_scripts(reload_scripts=True)");
WM_cursor_wait(0);
WM_event_add_notifier(C, NC_WINDOW, NULL);
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 0f4690c11d5..8a6b97b3834 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -56,6 +56,7 @@
#include "GPU_matrix.h"
#include "GPU_state.h"
#include "GPU_vertex_buffer.h"
+#include "GPU_viewport.h"
#include "ED_anim_api.h"
#include "ED_gpencil.h"
@@ -294,7 +295,7 @@ static void draw_seq_waveform(View2D *v2d,
/* Fcurve lookup is quite expensive, so do this after precondition. */
FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
@@ -350,7 +351,7 @@ static void draw_seq_waveform(View2D *v2d,
immEnd();
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
@@ -381,9 +382,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
offset = 0;
}
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
for (seq = seqbase->first; seq; seq = seq->next) {
chan_min = min_ii(chan_min, seq->machine);
@@ -443,7 +442,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1,
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* Get handle width in pixels. */
@@ -489,10 +488,9 @@ static void draw_seq_handle(View2D *v2d,
}
if (!(seq->type & SEQ_TYPE_EFFECT) || BKE_sequence_effect_get_num_inputs(seq->type) == 0) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
if (seq->flag & whichsel) {
if (seq_active) {
@@ -511,7 +509,7 @@ static void draw_seq_handle(View2D *v2d,
}
immRectf(pos, rx1, y1, rx2, y2);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* Draw numbers for start and end of the strip next to its handles. */
@@ -753,9 +751,7 @@ static void draw_sequence_extensions(Scene *scene, Sequence *seq, uint pos, floa
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
y2 = seq->machine + SEQ_STRIP_OFSTOP;
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
color3ubv_from_seq(scene, seq, col);
if (seq->flag & SELECT) {
@@ -781,7 +777,7 @@ static void draw_sequence_extensions(Scene *scene, Sequence *seq, uint pos, floa
imm_draw_box_wire_2d(
pos, x2, y2 + pixely, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, float y1)
@@ -791,7 +787,7 @@ static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y,
rgb_float_to_uchar(col, colvars->col);
if (seq->flag & SEQ_MUTE) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
col[3] = MUTE_ALPHA;
}
else {
@@ -812,7 +808,7 @@ static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y,
immEnd();
if (seq->flag & SEQ_MUTE) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
@@ -843,9 +839,7 @@ static void draw_seq_background(Scene *scene,
}
if (seq->flag & SEQ_MUTE) {
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
col[3] = MUTE_ALPHA;
}
@@ -910,13 +904,13 @@ static void draw_seq_background(Scene *scene,
}
if (seq->flag & SEQ_MUTE) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
static void draw_seq_locked(float x1, float y1, float x2, float y2)
{
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_DIAG_STRIPES);
@@ -930,12 +924,12 @@ static void draw_seq_locked(float x1, float y1, float x2, float y2)
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y)
{
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -943,7 +937,7 @@ static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y)
immRectf(pos, x1, y2, x2, text_margin_y);
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void calculate_seq_text_offsets(
@@ -1056,13 +1050,13 @@ static void draw_seq_fcurve(
GPU_vertbuf_data_len_set(vbo, vert_count);
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
GPU_batch_uniform_4f(batch, "color", 0.0f, 0.0f, 0.0f, 0.15f);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
if (vert_count > 0) {
GPU_batch_draw(batch);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_batch_discard(batch);
}
}
@@ -1180,7 +1174,7 @@ static void draw_effect_inputs_highlight(Sequence *seq)
Sequence *seq1 = seq->seq1;
Sequence *seq2 = seq->seq2;
Sequence *seq3 = seq->seq3;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1207,7 +1201,7 @@ static void draw_effect_inputs_highlight(Sequence *seq)
seq3->machine + SEQ_STRIP_OFSTOP);
}
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
void sequencer_special_update_set(Sequence *seq)
@@ -1537,7 +1531,7 @@ static void sequencer_preview_clear(void)
float col[3];
UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col);
- GPU_clear_color(col[0], col[1], col[2], 0.0);
+ GPU_clear_color(col[0], col[1], col[2], 1.0f);
GPU_clear(GPU_COLOR_BIT);
}
@@ -1594,9 +1588,7 @@ static void sequencer_draw_display_buffer(const bContext *C,
void *display_buffer;
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
}
/* Format needs to be created prior to any immBindShader call.
@@ -1681,7 +1673,7 @@ static void sequencer_draw_display_buffer(const bContext *C,
}
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
if (draw_backdrop) {
@@ -1775,6 +1767,13 @@ void sequencer_draw_preview(const bContext *C,
return;
}
+ /* Setup offscreen buffers. */
+ GPUViewport *viewport = WM_draw_region_get_viewport(region);
+
+ GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
+ GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
+ GPU_depth_test(false);
+
if (sseq->render_size == SEQ_PROXY_RENDER_SIZE_NONE) {
sequencer_preview_clear();
return;
@@ -1798,6 +1797,9 @@ void sequencer_draw_preview(const bContext *C,
ibuf = sequencer_ibuf_get(
bmain, depsgraph, scene, sseq, cfra, frame_ofs, names[sseq->multiview_eye]);
+ /* sequencer_ibuf_get can call GPU_framebuffer_bind. So disable srgb framebuffer again. */
+ GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
+
if (ibuf) {
scope = sequencer_get_scope(scene, sseq, ibuf, draw_backdrop);
@@ -1928,7 +1930,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
else if (last_seq->type == SEQ_TYPE_MULTICAM) {
int channel = last_seq->multicam_source;
if (channel != 0) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1937,7 +1939,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
immRectf(pos, v2d->cur.xmin, channel, v2d->cur.xmax, channel + 1);
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
}
@@ -1945,7 +1947,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
/* Draw highlight if "solo preview" is used. */
if (special_seq_update) {
const Sequence *seq = special_seq_update;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -1959,7 +1961,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
@@ -1969,7 +1971,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
const int frame_sta = scene->r.sfra;
const int frame_end = scene->r.efra + 1;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -2030,7 +2032,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
typedef struct CacheDrawData {
@@ -2154,7 +2156,7 @@ static void draw_cache_view(const bContext *C)
return;
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -2241,7 +2243,7 @@ static void draw_cache_view(const bContext *C)
draw_cache_view_batch(
userdata.final_out_vbo, userdata.final_out_vert_count, 1.0f, 0.4f, 0.2f, 0.4f);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* Draw sequencer timeline. */
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 99d4c2d9f1a..78ca2832c55 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -2642,6 +2642,8 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
seq = ed->seqbasep->first; /* Poll checks this is valid. */
+ BKE_sequencer_prefetch_stop(scene);
+
while (seq) {
if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) {
Sequence *seq_next;
@@ -2837,6 +2839,8 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ BKE_sequencer_prefetch_stop(scene);
+
/* Remove all selected from main list, and put in meta. */
seqm = BKE_sequence_alloc(ed->seqbasep, 1, 1, SEQ_TYPE_META); /* Channel number set later. */
@@ -2922,6 +2926,8 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
+ BKE_sequencer_prefetch_stop(scene);
+
for (seq = last_seq->seqbase.first; seq != NULL; seq = seq->next) {
BKE_sequence_invalidate_cache_composite(scene, seq);
}
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index e9ac6946032..f1b1d6760f3 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -1353,11 +1353,9 @@ static void draw_text_decoration(SpaceText *st, ARegion *region)
UI_GetThemeColor4fv(TH_TEXT, highlight_color);
highlight_color[3] = 0.1f;
immUniformColor4fv(highlight_color);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immRecti(pos, 0, y1, region->winx, y2);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
@@ -1708,9 +1706,9 @@ void draw_text_main(SpaceText *st, ARegion *region)
UI_GetThemeColor4fv(TH_TEXT, margin_color);
margin_color[3] = 0.2f;
immUniformColor4fv(margin_color);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immRecti(pos, margin_column_x, 0, margin_column_x + U.pixelsize, region->winy);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immUnbindProgram();
}
}
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 201f9dae5d5..688dce3c54e 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -55,6 +55,7 @@
#ifdef WITH_PYTHON
# include "BPY_extern.h"
+# include "BPY_extern_run.h"
#endif
#include "text_format.h"
@@ -756,7 +757,7 @@ static int text_run_script(bContext *C, ReportList *reports)
void *curl_prev = text->curl;
int curc_prev = text->curc;
- if (BPY_execute_text(C, text, reports, !is_live)) {
+ if (BPY_run_text(C, text, reports, !is_live)) {
if (is_live) {
/* for nice live updates */
WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 1ffa653372c..6969ecf197e 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -131,9 +131,7 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
/* Just to create the data to pass to immediate mode, grr! */
const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP);
if (facemap_data) {
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
const MVert *mvert = me->mvert;
const MPoly *mpoly = me->mpoly;
@@ -209,6 +207,6 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
GPU_batch_discard(draw_batch);
GPU_vertbuf_discard(vbo_pos);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index ac70547c293..33b365b45aa 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -588,9 +588,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
float alpha = 1.0f;
if (ca->passepartalpha != 1.0f) {
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
alpha = ca->passepartalpha;
}
@@ -609,7 +607,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
immRectf(shdr_pos, x1i, y1i, x2i, 0.0f);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
immUniformThemeColor3(TH_BACK);
@@ -668,7 +666,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
/* safety border */
if (ca) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformThemeColorAlpha(TH_VIEW_OVERLAY, 0.75f);
if (ca->dtx & CAM_DTX_CENTER) {
@@ -780,7 +778,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region,
imm_draw_box_wire_2d(shdr_pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
immUnbindProgram();
@@ -1027,9 +1025,7 @@ static void draw_view_axis(RegionView3D *rv3d, const rcti *rect)
/* draw axis lines */
GPU_line_width(2.0f);
GPU_line_smooth(true);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -1072,9 +1068,7 @@ static void draw_rotation_guide(const RegionView3D *rv3d)
negate_v3_v3(o, rv3d->ofs);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_depth_mask(false); /* don't overwrite zbuf */
GPUVertFormat *format = immVertexFormat();
@@ -1164,7 +1158,7 @@ static void draw_rotation_guide(const RegionView3D *rv3d)
immEnd();
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_depth_mask(true);
}
#endif /* WITH_INPUT_NDOF */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index ac9d12cdd58..5912bea4919 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -822,7 +822,7 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2])
float xaxis[3];
/* Radians per-pixel. */
- const float sensitivity = U.view_rotate_sensitivity_turntable / U.pixelsize;
+ const float sensitivity = U.view_rotate_sensitivity_turntable / U.dpi_fac;
/* Get the 3x3 matrix and its inverse from the quaternion */
quat_to_mat3(m, vod->curr.viewquat);
@@ -2015,7 +2015,7 @@ static void view_zoom_to_window_xy_3d(ARegion *region, float dfac, const int zoo
}
static float viewzoom_scale_value(const rcti *winrct,
- const short viewzoom,
+ const eViewZoom_Style viewzoom,
const bool zoom_invert,
const bool zoom_invert_force,
const int xy_curr[2],
@@ -2038,7 +2038,7 @@ static float viewzoom_scale_value(const rcti *winrct,
fac = (float)(xy_init[1] - xy_curr[1]);
}
- fac /= U.pixelsize;
+ fac /= U.dpi_fac;
if (zoom_invert != zoom_invert_force) {
fac = -fac;
@@ -2055,8 +2055,8 @@ static float viewzoom_scale_value(const rcti *winrct,
BLI_rcti_cent_x(winrct),
BLI_rcti_cent_y(winrct),
};
- float len_new = (5 * U.pixelsize) + ((float)len_v2v2_int(ctr, xy_curr) / U.pixelsize);
- float len_old = (5 * U.pixelsize) + ((float)len_v2v2_int(ctr, xy_init) / U.pixelsize);
+ float len_new = (5 * U.dpi_fac) + ((float)len_v2v2_int(ctr, xy_curr) / U.dpi_fac);
+ float len_old = (5 * U.dpi_fac) + ((float)len_v2v2_int(ctr, xy_init) / U.dpi_fac);
/* intentionally ignore 'zoom_invert' for scale */
if (zoom_invert_force) {
@@ -2066,16 +2066,16 @@ static float viewzoom_scale_value(const rcti *winrct,
zfac = val_orig * (len_old / max_ff(len_new, 1.0f)) / val;
}
else { /* USER_ZOOM_DOLLY */
- float len_new = 5 * U.pixelsize;
- float len_old = 5 * U.pixelsize;
+ float len_new = 5 * U.dpi_fac;
+ float len_old = 5 * U.dpi_fac;
if (U.uiflag & USER_ZOOM_HORIZ) {
- len_new += (winrct->xmax - (xy_curr[0])) / U.pixelsize;
- len_old += (winrct->xmax - (xy_init[0])) / U.pixelsize;
+ len_new += (winrct->xmax - (xy_curr[0])) / U.dpi_fac;
+ len_old += (winrct->xmax - (xy_init[0])) / U.dpi_fac;
}
else {
- len_new += (winrct->ymax - (xy_curr[1])) / U.pixelsize;
- len_old += (winrct->ymax - (xy_init[1])) / U.pixelsize;
+ len_new += (winrct->ymax - (xy_curr[1])) / U.dpi_fac;
+ len_old += (winrct->ymax - (xy_init[1])) / U.dpi_fac;
}
if (zoom_invert != zoom_invert_force) {
@@ -2089,7 +2089,7 @@ static float viewzoom_scale_value(const rcti *winrct,
}
static float viewzoom_scale_value_offset(const rcti *winrct,
- const short viewzoom,
+ const eViewZoom_Style viewzoom,
const bool zoom_invert,
const bool zoom_invert_force,
const int xy_curr[2],
@@ -2120,7 +2120,7 @@ static float viewzoom_scale_value_offset(const rcti *winrct,
static void viewzoom_apply_camera(ViewOpsData *vod,
const int xy[2],
- const short viewzoom,
+ const eViewZoom_Style viewzoom,
const bool zoom_invert,
const bool zoom_to_pos)
{
@@ -2155,7 +2155,7 @@ static void viewzoom_apply_camera(ViewOpsData *vod,
static void viewzoom_apply_3d(ViewOpsData *vod,
const int xy[2],
- const short viewzoom,
+ const eViewZoom_Style viewzoom,
const bool zoom_invert,
const bool zoom_to_pos)
{
@@ -2197,7 +2197,7 @@ static void viewzoom_apply_3d(ViewOpsData *vod,
static void viewzoom_apply(ViewOpsData *vod,
const int xy[2],
- const short viewzoom,
+ const eViewZoom_Style viewzoom,
const bool zoom_invert,
const bool zoom_to_pos)
{
@@ -2248,7 +2248,7 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init");
viewzoom_apply(vod,
&event->x,
- U.viewzoom,
+ (eViewZoom_Style)U.viewzoom,
(U.uiflag & USER_ZOOM_INVERT) != 0,
(use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS)));
if (ED_screen_animation_playing(CTX_wm_manager(C))) {
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
index 3ce4c8dc9a8..5f8ffc5f3f9 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c
@@ -407,7 +407,7 @@ static void axis_geom_draw(const wmGizmo *gz,
BLF_width_and_height(font.id, axis_str, 2, &offset[0], &offset[1]);
BLF_position(font.id, roundf(offset[0] * -0.5f), roundf(offset[1] * -0.5f), 0);
BLF_draw_ascii(font.id, axis_str, 2);
- GPU_blend(true); /* XXX, blf disables */
+ GPU_blend(GPU_BLEND_ALPHA); /* XXX, blf disables */
GPU_matrix_pop();
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -465,9 +465,9 @@ static void axis3d_draw_intern(const bContext *C,
UNUSED_VARS(C);
#endif
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
axis_geom_draw(gz, color, select, &draw_info);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_matrix_pop();
}
@@ -478,9 +478,9 @@ static void gizmo_axis_draw(const bContext *C, wmGizmo *gz)
(void)is_modal;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
axis3d_draw_intern(C, gz, false, is_highlight);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static int gizmo_axis_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
index 7799aba5c19..5aba1fecc53 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
@@ -607,7 +607,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
GPU_matrix_projection_set(rv3d->winmat);
GPU_matrix_set(rv3d->viewmat);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
const uint shdr_pos_3d = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@@ -735,7 +735,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
rot_90_vec_b[1] = dir_ruler[0];
normalize_v2(rot_90_vec_b);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
if (proj_ok[1] && is_act && (ruler_item->flag & RULERITEM_USE_ANGLE_ACTIVE)) {
GPU_line_width(3.0f);
@@ -781,7 +781,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
immEnd();
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* text */
@@ -800,13 +800,13 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
/* draw text (bg) */
if (proj_ok[1]) {
immUniformColor4fv(color_back);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immRectf(shdr_pos_2d,
posit[0] - bg_margin,
posit[1] - bg_margin,
posit[0] + bg_margin + numstr_size[0],
posit[1] + bg_margin + numstr_size[1]);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
immUnbindProgram();
@@ -831,7 +831,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
normalize_v2(rot_90_vec);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniformColor3ubv(color_wire);
@@ -855,7 +855,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
immEnd();
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
/* text */
@@ -877,13 +877,13 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
/* draw text (bg) */
if (proj_ok[0] && proj_ok[2]) {
immUniformColor4fv(color_back);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immRectf(shdr_pos_2d,
posit[0] - bg_margin,
posit[1] - bg_margin,
posit[0] + bg_margin + numstr_size[0],
posit[1] + bg_margin + numstr_size[1]);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
immUnbindProgram();
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index a21c1458286..6c61c83731d 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -258,7 +258,7 @@ static void draw_line_loop(const float coords[][3], int coords_len, const float
GPU_vertbuf_attr_set(vert, pos, i, coords[i]);
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vert, NULL, GPU_BATCH_OWNS_VBO);
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
@@ -272,7 +272,7 @@ static void draw_line_loop(const float coords[][3], int coords_len, const float
GPU_batch_draw(batch);
GPU_batch_discard(batch);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void draw_line_pairs(const float coords_a[][3],
@@ -291,7 +291,7 @@ static void draw_line_pairs(const float coords_a[][3],
GPU_vertbuf_attr_set(vert, pos, (i * 2) + 1, coords_b[i]);
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_LINES, vert, NULL, GPU_BATCH_OWNS_VBO);
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
@@ -305,7 +305,7 @@ static void draw_line_pairs(const float coords_a[][3],
GPU_batch_draw(batch);
GPU_batch_discard(batch);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void draw_line_bounds(const BoundBox *bounds, const float color[4])
@@ -339,7 +339,7 @@ static void draw_line_bounds(const BoundBox *bounds, const float color[4])
GPU_vertbuf_attr_set(vert, pos, j++, bounds->vec[edges[i][1]]);
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_LINES, vert, NULL, GPU_BATCH_OWNS_VBO);
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
@@ -353,7 +353,7 @@ static void draw_line_bounds(const BoundBox *bounds, const float color[4])
GPU_batch_draw(batch);
GPU_batch_discard(batch);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static bool calc_bbox(struct InteractivePlaceData *ipd, BoundBox *bounds)
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 76cce5e725f..2fa291e7ae4 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1544,16 +1544,14 @@ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *region)
#endif
/* autokey recording icon... */
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
xco -= U.widget_unit;
yco -= (int)printable_size[1] / 2;
UI_icon_draw(xco, yco, ICON_REC);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
static void drawTransformPixel(const struct bContext *C, ARegion *region, void *arg)
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index d0e37f22236..0aa6b4f6131 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -884,7 +884,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
float viewport[4];
GPU_viewport_size_get_f(viewport);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immUniform2fv("viewportSize", &viewport[2]);
immUniform1f("lineWidth", 3.0f * U.pixelsize);
diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c
index 2e92b4e5c09..61af4ebbe46 100644
--- a/source/blender/editors/transform/transform_convert_object.c
+++ b/source/blender/editors/transform/transform_convert_object.c
@@ -357,7 +357,7 @@ static void set_trans_object_base_flags(TransInfo *t)
/* Makes sure base flags and object flags are identical. */
BKE_scene_base_flag_to_objects(t->view_layer);
/* Make sure depsgraph is here. */
- DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
+ DEG_graph_relations_update(depsgraph);
/* Clear all flags we need. It will be used to detect dependencies. */
trans_object_base_deps_flag_prepare(view_layer);
/* Traverse all bases and set all possible flags. */
diff --git a/source/blender/editors/transform/transform_draw_cursors.c b/source/blender/editors/transform/transform_draw_cursors.c
index 95ca5ae0c30..84fc45e2b45 100644
--- a/source/blender/editors/transform/transform_draw_cursors.c
+++ b/source/blender/editors/transform/transform_draw_cursors.c
@@ -191,7 +191,7 @@ void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customd
}
GPU_line_smooth(true);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_matrix_push();
@@ -339,6 +339,6 @@ void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customd
GPU_matrix_pop();
GPU_line_smooth(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 6155042f555..dffee72205b 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -1344,7 +1344,7 @@ void drawDial3d(const TransInfo *t)
gizmo_get_axis_color(axis_idx, NULL, color, color);
GPU_depth_test(false);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
ED_gizmotypes_dial_3d_draw_util(mat_basis,
@@ -1360,7 +1360,7 @@ void drawDial3d(const TransInfo *t)
GPU_line_smooth(false);
GPU_depth_test(true);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c
index 1886f95beae..45debe964f4 100644
--- a/source/blender/editors/transform/transform_mode_edge_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_slide.c
@@ -1149,9 +1149,7 @@ void drawEdgeSlide(TransInfo *t)
GPU_depth_test(false);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_matrix_push();
GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
@@ -1266,7 +1264,7 @@ void drawEdgeSlide(TransInfo *t)
GPU_matrix_pop();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_depth_test(true);
}
diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c
index 38537194af3..11d0b375e6f 100644
--- a/source/blender/editors/transform/transform_mode_vert_slide.c
+++ b/source/blender/editors/transform/transform_mode_vert_slide.c
@@ -392,9 +392,7 @@ void drawVertSlide(TransInfo *t)
GPU_depth_test(false);
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_matrix_push();
GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat);
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index a700dd320b7..09b5df82c2b 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -245,7 +245,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
uint pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -271,7 +271,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
}
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index 384da6fb931..041b2fec00b 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -38,7 +38,7 @@
#include "WM_types.h"
#ifdef WITH_PYTHON
-# include "BPY_extern.h"
+# include "BPY_extern_run.h"
#endif
#include "ED_numinput.h"
@@ -294,10 +294,10 @@ bool user_string_to_number(bContext *C,
bUnit_ReplaceString(
str_unit_convert, sizeof(str_unit_convert), str, unit_scale, unit->system, type);
- return BPY_execute_string_as_number(C, NULL, str_unit_convert, error_prefix, r_value);
+ return BPY_run_string_as_number(C, NULL, str_unit_convert, error_prefix, r_value);
}
- int success = BPY_execute_string_as_number(C, NULL, str, error_prefix, r_value);
+ int success = BPY_run_string_as_number(C, NULL, str, error_prefix, r_value);
*r_value *= bUnit_PreferredInputUnitScalar(unit, type);
*r_value /= unit_scale;
return success;
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index f26e95d8861..faeefcb989e 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -237,10 +237,10 @@ static void draw_uvs_shadow(SpaceImage *sima,
if (edges) {
if (sima->flag & SI_SMOOTH_UV) {
GPU_line_smooth(true);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
}
else if (overlay_alpha < 1.0f) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
}
col[3] = overlay_alpha;
@@ -250,10 +250,10 @@ static void draw_uvs_shadow(SpaceImage *sima,
if (sima->flag & SI_SMOOTH_UV) {
GPU_line_smooth(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
else if (overlay_alpha < 1.0f) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
}
@@ -349,8 +349,7 @@ static void draw_uvs(SpaceImage *sima,
interpedges = (ts->uv_selectmode == UV_SELECT_VERTEX);
}
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
if (batch->faces) {
GPU_batch_program_set_builtin(batch->faces,
@@ -360,7 +359,7 @@ static void draw_uvs(SpaceImage *sima,
GPU_SHADER_2D_UV_FACES);
if (!draw_stretch) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
UI_GetThemeColor4fv(TH_FACE, col1);
UI_GetThemeColor4fv(TH_FACE_SELECT, col2);
@@ -387,16 +386,16 @@ static void draw_uvs(SpaceImage *sima,
GPU_batch_draw(batch->faces);
if (!draw_stretch) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
if (batch->edges) {
if (sima->flag & SI_SMOOTH_UV) {
GPU_line_smooth(true);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
}
else if (overlay_alpha < 1.0f) {
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
}
{
@@ -465,10 +464,10 @@ static void draw_uvs(SpaceImage *sima,
if (sima->flag & SI_SMOOTH_UV) {
GPU_line_smooth(false);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
else if (overlay_alpha < 1.0f) {
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
@@ -478,7 +477,7 @@ static void draw_uvs(SpaceImage *sima,
const float point_size = UI_GetThemeValuef(TH_VERTEX_SIZE);
const float pinned_col[4] = {1.0f, 0.0f, 0.0f, 1.0f}; /* TODO Theme? */
UI_GetThemeColor4fv(TH_VERTEX, col1);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_program_point_size(true);
GPU_batch_program_set_builtin(batch->verts, GPU_SHADER_2D_UV_VERTS);
@@ -498,7 +497,7 @@ static void draw_uvs(SpaceImage *sima,
GPU_batch_uniform_4fv(batch->verts, "selectColor", col2);
GPU_batch_draw(batch->verts);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_program_point_size(false);
}
if (batch->facedots) {
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 6332a6ab48f..6dac31794b4 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -1765,7 +1765,7 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void
pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
}
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
/* Static Tris */
if (stitch_preview->static_tris) {
@@ -1829,7 +1829,7 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void
stitch_draw_vbo(vbo_line, GPU_PRIM_LINES, col);
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
/* draw stitch vert/lines preview */
if (ssc->mode == STITCH_VERT) {
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 68b5b4baeca..4b2fd7b6735 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -869,8 +869,7 @@ Render *BlenderStrokeRenderer::RenderScene(Render * /*re*/, bool render)
#endif
Render *freestyle_render = RE_NewSceneRender(freestyle_scene);
- ViewLayer *view_layer = (ViewLayer *)freestyle_scene->view_layers.first;
- DEG_graph_relations_update(freestyle_depsgraph, freestyle_bmain, freestyle_scene, view_layer);
+ DEG_graph_relations_update(freestyle_depsgraph);
RE_RenderFreestyleStrokes(
freestyle_render, freestyle_bmain, freestyle_scene, render && get_stroke_count() > 0);
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 388c2f35774..2446bfc13dc 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -655,7 +655,7 @@ void FRS_do_stroke_rendering(Render *re, ViewLayer *view_layer)
ViewLayer *scene_view_layer = (ViewLayer *)BLI_findstring(
&re->scene->view_layers, view_layer->name, offsetof(ViewLayer, name));
Depsgraph *depsgraph = DEG_graph_new(re->main, re->scene, scene_view_layer, DAG_EVAL_RENDER);
- BKE_scene_graph_update_for_newframe(depsgraph, re->main);
+ BKE_scene_graph_update_for_newframe(depsgraph);
// prepare Freestyle:
// - load mesh
diff --git a/source/blender/freestyle/intern/system/PythonInterpreter.h b/source/blender/freestyle/intern/system/PythonInterpreter.h
index bae69aa0a42..50ebacbd6e8 100644
--- a/source/blender/freestyle/intern/system/PythonInterpreter.h
+++ b/source/blender/freestyle/intern/system/PythonInterpreter.h
@@ -42,7 +42,7 @@ extern "C" {
#include "BKE_report.h"
#include "BKE_text.h"
-#include "BPY_extern.h"
+#include "BPY_extern_run.h"
#include "bpy_capi_utils.h"
@@ -68,12 +68,12 @@ class PythonInterpreter : public Interpreter {
BKE_reports_clear(reports);
char *fn = const_cast<char *>(filename.c_str());
#if 0
- bool ok = BPY_execute_filepath(_context, fn, reports);
+ bool ok = BPY_run_filepath(_context, fn, reports);
#else
bool ok;
Text *text = BKE_text_load(&_freestyle_bmain, fn, G_MAIN->name);
if (text) {
- ok = BPY_execute_text(_context, text, reports, false);
+ ok = BPY_run_text(_context, text, reports, false);
BKE_id_delete(&_freestyle_bmain, text);
}
else {
@@ -102,7 +102,7 @@ class PythonInterpreter : public Interpreter {
BKE_reports_clear(reports);
- if (!BPY_execute_string(_context, NULL, str.c_str())) {
+ if (!BPY_run_string_eval(_context, NULL, str.c_str())) {
BPy_errors_to_report(reports);
cerr << "\nError executing Python script from PythonInterpreter::interpretString" << endl;
cerr << "Name: " << name << endl;
@@ -122,7 +122,7 @@ class PythonInterpreter : public Interpreter {
BKE_reports_clear(reports);
- if (!BPY_execute_text(_context, text, reports, false)) {
+ if (!BPY_run_text(_context, text, reports, false)) {
cerr << "\nError executing Python script from PythonInterpreter::interpretText" << endl;
cerr << "Name: " << name << endl;
cerr << "Errors: " << endl;
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c
index 60c3877b89a..41365da1153 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c
@@ -128,7 +128,10 @@ static void deformStroke(GpencilModifierData *md,
BKE_gpencil_stroke_geometry_update(gps);
}
-static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob)
+static void bakeModifier(Main *UNUSED(bmain),
+ Depsgraph *depsgraph,
+ GpencilModifierData *md,
+ Object *ob)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
@@ -147,7 +150,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData
* NOTE: this assumes that we don't want armature animation on non-keyframed frames
*/
CFRA = gpf->framenum;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
/* compute armature effects on this frame */
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
@@ -158,7 +161,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData
/* return frame state and DB to original state */
CFRA = oldframe;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
index 30ac18c64ae..1608d7a2d4c 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
@@ -280,7 +280,10 @@ static void deformStroke(GpencilModifierData *md,
/* FIXME: Ideally we be doing this on a copy of the main depsgraph
* (i.e. one where we don't have to worry about restoring state)
*/
-static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob)
+static void bakeModifier(Main *UNUSED(bmain),
+ Depsgraph *depsgraph,
+ GpencilModifierData *md,
+ Object *ob)
{
HookGpencilModifierData *mmd = (HookGpencilModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@@ -297,7 +300,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData
* NOTE: this assumes that we don't want hook animation on non-keyframed frames
*/
CFRA = gpf->framenum;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
/* compute hook effects on this frame */
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
@@ -308,7 +311,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData
/* return frame state and DB to original state */
CFRA = oldframe;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
static void freeData(GpencilModifierData *md)
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c
index 0f5fc4d5cf6..2d2f39f0189 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c
@@ -126,7 +126,10 @@ static void deformStroke(GpencilModifierData *md,
/* FIXME: Ideally we be doing this on a copy of the main depsgraph
* (i.e. one where we don't have to worry about restoring state)
*/
-static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob)
+static void bakeModifier(Main *UNUSED(bmain),
+ Depsgraph *depsgraph,
+ GpencilModifierData *md,
+ Object *ob)
{
LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@@ -144,7 +147,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData
* NOTE: this assumes that we don't want lattice animation on non-keyframed frames
*/
CFRA = gpf->framenum;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
/* recalculate lattice data */
BKE_gpencil_lattice_init(ob);
@@ -165,7 +168,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData
/* return frame state and DB to original state */
CFRA = oldframe;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
static void freeData(GpencilModifierData *md)
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c
index c99ca64325c..3554cf2e4eb 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c
@@ -174,7 +174,10 @@ static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Objec
}
}
-static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob)
+static void bakeModifier(Main *UNUSED(bmain),
+ Depsgraph *depsgraph,
+ GpencilModifierData *md,
+ Object *ob)
{
Scene *scene = DEG_get_evaluated_scene(depsgraph);
bGPdata *gpd = ob->data;
@@ -184,7 +187,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
/* apply mirror effects on this frame */
CFRA = gpf->framenum;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
/* compute mirror effects on this frame */
generate_geometry(md, ob, gpl, gpf);
@@ -193,7 +196,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData
/* return frame state and DB to original state */
CFRA = oldframe;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
static bool isDisabled(GpencilModifierData *UNUSED(md), int UNUSED(userRenderParams))
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
index 9d10fcbe49b..9e86ea6ecdc 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
@@ -259,7 +259,10 @@ static void deformStroke(GpencilModifierData *md,
/* FIXME: Ideally we be doing this on a copy of the main depsgraph
* (i.e. one where we don't have to worry about restoring state)
*/
-static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob)
+static void bakeModifier(Main *UNUSED(bmain),
+ Depsgraph *depsgraph,
+ GpencilModifierData *md,
+ Object *ob)
{
TintGpencilModifierData *mmd = (TintGpencilModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@@ -276,7 +279,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData
* NOTE: this assumes that we don't want animation on non-keyframed frames
*/
CFRA = gpf->framenum;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
/* compute effects on this frame */
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
@@ -287,7 +290,7 @@ static void bakeModifier(Main *bmain, Depsgraph *depsgraph, GpencilModifierData
/* return frame state and DB to original state */
CFRA = oldframe;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
static void freeData(GpencilModifierData *md)
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 906ae31fbc7..45b379c5e0a 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -92,6 +92,8 @@ set(SRC
opengl/gl_batch.cc
opengl/gl_context.cc
opengl/gl_drawlist.cc
+ opengl/gl_shader.cc
+ opengl/gl_state.cc
opengl/gl_vertex_array.cc
GPU_attr_binding.h
@@ -137,13 +139,16 @@ set(SRC
intern/gpu_primitive_private.h
intern/gpu_private.h
intern/gpu_select_private.h
- intern/gpu_shader_private.h
+ intern/gpu_shader_private.hh
+ intern/gpu_state_private.hh
intern/gpu_vertex_format_private.h
opengl/gl_backend.hh
opengl/gl_batch.hh
opengl/gl_context.hh
opengl/gl_drawlist.hh
+ opengl/gl_shader.hh
+ opengl/gl_state.hh
opengl/gl_vertex_array.hh
)
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index d57739156f8..e87ad328f1d 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -128,18 +128,24 @@ void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
eGPUShaderConfig sh_cfg);
/* Will only work after setting the batch program. */
-void GPU_batch_uniform_1i(GPUBatch *, const char *name, int value);
-void GPU_batch_uniform_1b(GPUBatch *, const char *name, bool value);
-void GPU_batch_uniform_1f(GPUBatch *, const char *name, float value);
-void GPU_batch_uniform_2f(GPUBatch *, const char *name, float x, float y);
-void GPU_batch_uniform_3f(GPUBatch *, const char *name, float x, float y, float z);
-void GPU_batch_uniform_4f(GPUBatch *, const char *name, float x, float y, float z, float w);
-void GPU_batch_uniform_2fv(GPUBatch *, const char *name, const float data[2]);
-void GPU_batch_uniform_3fv(GPUBatch *, const char *name, const float data[3]);
-void GPU_batch_uniform_4fv(GPUBatch *, const char *name, const float data[4]);
-void GPU_batch_uniform_2fv_array(GPUBatch *, const char *name, const int len, const float *data);
-void GPU_batch_uniform_4fv_array(GPUBatch *, const char *name, const int len, const float *data);
-void GPU_batch_uniform_mat4(GPUBatch *, const char *name, const float data[4][4]);
+/* TODO(fclem) Theses needs to be replaced by GPU_shader_uniform_* with explicit shader. */
+#define GPU_batch_uniform_1i(batch, name, x) GPU_shader_uniform_1i((batch)->shader, name, x);
+#define GPU_batch_uniform_1b(batch, name, x) GPU_shader_uniform_1b((batch)->shader, name, x);
+#define GPU_batch_uniform_1f(batch, name, x) GPU_shader_uniform_1f((batch)->shader, name, x);
+#define GPU_batch_uniform_2f(batch, name, x, y) GPU_shader_uniform_2f((batch)->shader, name, x, y);
+#define GPU_batch_uniform_3f(batch, name, x, y, z) \
+ GPU_shader_uniform_3f((batch)->shader, name, x, y, z);
+#define GPU_batch_uniform_4f(batch, name, x, y, z, w) \
+ GPU_shader_uniform_4f((batch)->shader, name, x, y, z, w);
+#define GPU_batch_uniform_2fv(batch, name, val) GPU_shader_uniform_2fv((batch)->shader, name, val);
+#define GPU_batch_uniform_3fv(batch, name, val) GPU_shader_uniform_3fv((batch)->shader, name, val);
+#define GPU_batch_uniform_4fv(batch, name, val) GPU_shader_uniform_4fv((batch)->shader, name, val);
+#define GPU_batch_uniform_2fv_array(batch, name, len, val) \
+ GPU_shader_uniform_2fv_array((batch)->shader, name, len, val);
+#define GPU_batch_uniform_4fv_array(batch, name, len, val) \
+ GPU_shader_uniform_4fv_array((batch)->shader, name, len, val);
+#define GPU_batch_uniform_mat4(batch, name, val) \
+ GPU_shader_uniform_mat4((batch)->shader, name, val);
void GPU_batch_draw(GPUBatch *batch);
void GPU_batch_draw_range(GPUBatch *batch, int v_first, int v_count);
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index 9dc07fefd4e..7103317e4d6 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -61,6 +61,7 @@ typedef struct GPUOffScreen GPUOffScreen;
GPUFrameBuffer *GPU_framebuffer_create(void);
void GPU_framebuffer_free(GPUFrameBuffer *fb);
void GPU_framebuffer_bind(GPUFrameBuffer *fb);
+void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *fb);
void GPU_framebuffer_restore(void);
bool GPU_framebuffer_bound(GPUFrameBuffer *fb);
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index b8957ff1819..9dcf9b7d5bb 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -112,15 +112,6 @@ typedef enum eGPUMatFlag {
GPU_MATFLAG_BARYCENTRIC = (1 << 4),
} eGPUMatFlag;
-typedef enum eGPUBlendMode {
- GPU_BLEND_SOLID = 0,
- GPU_BLEND_ADD = 1,
- GPU_BLEND_ALPHA = 2,
- GPU_BLEND_CLIP = 4,
- GPU_BLEND_ALPHA_SORT = 8,
- GPU_BLEND_ALPHA_TO_COVERAGE = 16,
-} eGPUBlendMode;
-
typedef struct GPUNodeStack {
eGPUType type;
float vec[4];
diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h
index 7b94a535a30..aad6ae9e2ba 100644
--- a/source/blender/gpu/GPU_matrix.h
+++ b/source/blender/gpu/GPU_matrix.h
@@ -29,7 +29,7 @@
extern "C" {
#endif
-struct GPUShaderInterface;
+struct GPUShader;
void GPU_matrix_reset(void); /* to Identity transform & empty stack */
@@ -147,7 +147,7 @@ const float (*GPU_matrix_normal_get(float m[3][3]))[3];
const float (*GPU_matrix_normal_inverse_get(float m[3][3]))[3];
/* set uniform values for currently bound shader */
-void GPU_matrix_bind(const struct GPUShaderInterface *);
+void GPU_matrix_bind(struct GPUShader *shader);
bool GPU_matrix_dirty_get(void); /* since last bind */
/* own working polygon offset */
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 0b9109fbd4b..99fcae19984 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -27,14 +27,19 @@
extern "C" {
#endif
-typedef struct GPUShader GPUShader;
struct GPUShaderInterface;
struct GPUTexture;
struct GPUUniformBuffer;
+struct GPUVertBuf;
-/* GPU Shader
- * - only for fragment shaders now
- * - must call texture bind before setting a texture as uniform! */
+/* TODO(fclem) These members should be private and the
+ * whole struct should just be an opaque pointer. */
+typedef struct GPUShader {
+ /** Uniform & attribute locations for shader. */
+ struct GPUShaderInterface *interface;
+ /** For debugging purpose. */
+ char name[64];
+} GPUShader;
typedef enum eGPUShaderTFBType {
GPU_SHADER_TFB_NONE = 0, /* Transform feedback unsupported. */
@@ -63,17 +68,16 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
const char **tf_names,
const int tf_count,
const char *shader_name);
-GPUShader *GPU_shader_load_from_binary(const char *binary,
- const int binary_format,
- const int binary_len,
- const char *shname);
+
struct GPU_ShaderCreateFromArray_Params {
const char **vert, **geom, **frag, **defs;
};
struct GPUShader *GPU_shader_create_from_arrays_impl(
- const struct GPU_ShaderCreateFromArray_Params *params);
+ const struct GPU_ShaderCreateFromArray_Params *params, const char *func, int line);
+
#define GPU_shader_create_from_arrays(...) \
- GPU_shader_create_from_arrays_impl(&(const struct GPU_ShaderCreateFromArray_Params)__VA_ARGS__)
+ GPU_shader_create_from_arrays_impl( \
+ &(const struct GPU_ShaderCreateFromArray_Params)__VA_ARGS__, __func__, __LINE__)
void GPU_shader_free(GPUShader *shader);
@@ -81,12 +85,12 @@ void GPU_shader_bind(GPUShader *shader);
void GPU_shader_unbind(void);
/* Returns true if transform feedback was successfully enabled. */
-bool GPU_shader_transform_feedback_enable(GPUShader *shader, unsigned int vbo_id);
+bool GPU_shader_transform_feedback_enable(GPUShader *shader, struct GPUVertBuf *vertbuf);
void GPU_shader_transform_feedback_disable(GPUShader *shader);
int GPU_shader_get_program(GPUShader *shader);
-void GPU_shader_set_srgb_uniform(const struct GPUShaderInterface *interface);
+void GPU_shader_set_srgb_uniform(GPUShader *shader);
int GPU_shader_get_uniform(GPUShader *shader, const char *name);
int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin);
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index 4a2c90e241b..be3250f6654 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -20,49 +20,92 @@
#pragma once
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "BLI_utildefines.h"
+
+typedef enum eGPUWriteMask {
+ GPU_WRITE_NONE = 0,
+ GPU_WRITE_RED = (1 << 0),
+ GPU_WRITE_GREEN = (1 << 1),
+ GPU_WRITE_BLUE = (1 << 2),
+ GPU_WRITE_ALPHA = (1 << 3),
+ GPU_WRITE_DEPTH = (1 << 4),
+ GPU_WRITE_COLOR = (GPU_WRITE_RED | GPU_WRITE_GREEN | GPU_WRITE_BLUE | GPU_WRITE_ALPHA),
+} eGPUWriteMask;
+
+ENUM_OPERATORS(eGPUWriteMask)
+
+/**
+ * Defines the fixed pipeline blending equation.
+ * SRC is the output color from the shader.
+ * DST is the color from the framebuffer.
+ * The blending equation is :
+ * (SRC * A) + (DST * B).
+ * The blend mode will modify the A and B parameters.
+ */
+typedef enum eGPUBlend {
+ GPU_BLEND_NONE = 0,
+ /** Premult variants will _NOT_ multiply rgb output by alpha. */
+ GPU_BLEND_ALPHA,
+ GPU_BLEND_ALPHA_PREMULT,
+ GPU_BLEND_ADDITIVE,
+ GPU_BLEND_ADDITIVE_PREMULT,
+ GPU_BLEND_MULTIPLY,
+ GPU_BLEND_SUBTRACT,
+ /** Replace logic op: SRC * (1 - DST)
+ * NOTE: Does not modify alpha. */
+ GPU_BLEND_INVERT,
+ /** Order independent transparency.
+ * NOTE: Cannot be used as is. Needs special setup (framebuffer, shader ...). */
+ GPU_BLEND_OIT,
+ /** Special blend to add color under and multiply dst color by src alpha. */
+ GPU_BLEND_BACKGROUND,
+ /** Custom blend parameters using dual source blending : SRC0 + SRC1 * DST
+ * NOTE: Can only be used with _ONE_ Draw Buffer and shader needs to be specialized. */
+ GPU_BLEND_CUSTOM,
+} eGPUBlend;
+
+typedef enum eGPUDepthTest {
+ GPU_DEPTH_NONE = 0,
+ GPU_DEPTH_ALWAYS,
+ GPU_DEPTH_LESS,
+ GPU_DEPTH_LESS_EQUAL,
+ GPU_DEPTH_EQUAL,
+ GPU_DEPTH_GREATER,
+ GPU_DEPTH_GREATER_EQUAL,
+} eGPUDepthTest;
+
+typedef enum eGPUStencilTest {
+ GPU_STENCIL_NONE = 0,
+ GPU_STENCIL_ALWAYS,
+ GPU_STENCIL_EQUAL,
+ GPU_STENCIL_NEQUAL,
+} eGPUStencilTest;
+
+typedef enum eGPUStencilOp {
+ GPU_STENCIL_OP_NONE = 0,
+ GPU_STENCIL_OP_REPLACE,
+ /** Special values for stencil shadows. */
+ GPU_STENCIL_OP_COUNT_DEPTH_PASS,
+ GPU_STENCIL_OP_COUNT_DEPTH_FAIL,
+} eGPUStencilOp;
-/* These map directly to the GL_ blend functions, to minimize API add as needed*/
-typedef enum eGPUBlendFunction {
- GPU_ONE,
- GPU_SRC_ALPHA,
- GPU_ONE_MINUS_SRC_ALPHA,
- GPU_DST_COLOR,
- GPU_ZERO,
-} eGPUBlendFunction;
-
-/* These map directly to the GL_ filter functions, to minimize API add as needed*/
-typedef enum eGPUFilterFunction {
- GPU_NEAREST,
- GPU_LINEAR,
-} eGPUFilterFunction;
-
-typedef enum eGPUFaceCull {
+typedef enum eGPUFaceCullTest {
GPU_CULL_NONE = 0, /* Culling disabled. */
GPU_CULL_FRONT,
GPU_CULL_BACK,
-} eGPUFaceCull;
+} eGPUFaceCullTest;
typedef enum eGPUProvokingVertex {
- GPU_VERTEX_FIRST = 0,
- GPU_VERTEX_LAST, /* Default */
+ GPU_VERTEX_LAST = 0, /* Default. */
+ GPU_VERTEX_FIRST = 1, /* Follow Blender loop order. */
} eGPUProvokingVertex;
-/* Initialize
- * - sets the default Blender opengl state, if in doubt, check
- * the contents of this function
- * - this is called when starting Blender, for opengl rendering. */
-void GPU_state_init(void);
-
-void GPU_blend(bool enable);
-void GPU_blend_set_func(eGPUBlendFunction sfactor, eGPUBlendFunction dfactor);
-void GPU_blend_set_func_separate(eGPUBlendFunction src_rgb,
- eGPUBlendFunction dst_rgb,
- eGPUBlendFunction src_alpha,
- eGPUBlendFunction dst_alpha);
-void GPU_face_culling(eGPUFaceCull culling);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GPU_blend(eGPUBlend blend);
+void GPU_face_culling(eGPUFaceCullTest culling);
void GPU_front_facing(bool invert);
void GPU_provoking_vertex(eGPUProvokingVertex vert);
void GPU_depth_range(float near, float far);
@@ -71,39 +114,40 @@ bool GPU_depth_test_enabled(void);
void GPU_scissor_test(bool enable);
void GPU_line_smooth(bool enable);
void GPU_line_width(float width);
+void GPU_logic_op_xor_set(bool enable);
void GPU_point_size(float size);
void GPU_polygon_smooth(bool enable);
void GPU_program_point_size(bool enable);
void GPU_scissor(int x, int y, int width, int height);
-void GPU_scissor_get_f(float coords[4]);
-void GPU_scissor_get_i(int coords[4]);
+void GPU_scissor_get(int coords[4]);
void GPU_viewport(int x, int y, int width, int height);
void GPU_viewport_size_get_f(float coords[4]);
void GPU_viewport_size_get_i(int coords[4]);
+void GPU_write_mask(eGPUWriteMask mask);
void GPU_color_mask(bool r, bool g, bool b, bool a);
void GPU_depth_mask(bool depth);
bool GPU_depth_mask_get(void);
-void GPU_stencil_mask(uint stencil);
void GPU_unpack_row_length_set(uint len);
+void GPU_shadow_offset(bool enable);
void GPU_clip_distances(int enabled_len);
bool GPU_mipmap_enabled(void);
+void GPU_state_set(eGPUWriteMask write_mask,
+ eGPUBlend blend,
+ eGPUFaceCullTest culling_test,
+ eGPUDepthTest depth_test,
+ eGPUStencilTest stencil_test,
+ eGPUStencilOp stencil_op,
+ eGPUProvokingVertex provoking_vert);
-void GPU_flush(void);
-void GPU_finish(void);
+void GPU_stencil_reference_set(uint reference);
+void GPU_stencil_write_mask_set(uint write_mask);
+void GPU_stencil_compare_mask_set(uint compare_mask);
-void GPU_logic_op_xor_set(bool enable);
+eGPUBlend GPU_blend_get(void);
+eGPUWriteMask GPU_write_mask_get(void);
-/* Attribute push & pop. */
-typedef enum eGPUAttrMask {
- GPU_DEPTH_BUFFER_BIT = (1 << 0),
- GPU_ENABLE_BIT = (1 << 1),
- GPU_SCISSOR_BIT = (1 << 2),
- GPU_VIEWPORT_BIT = (1 << 3),
- GPU_BLEND_BIT = (1 << 4),
-} eGPUAttrMask;
-
-void gpuPushAttr(eGPUAttrMask mask);
-void gpuPopAttr(void);
+void GPU_flush(void);
+void GPU_finish(void);
#ifdef __cplusplus
}
diff --git a/source/blender/gpu/intern/gpu_backend.hh b/source/blender/gpu/intern/gpu_backend.hh
index 25d165098a7..ab6e9cd7351 100644
--- a/source/blender/gpu/intern/gpu_backend.hh
+++ b/source/blender/gpu/intern/gpu_backend.hh
@@ -28,6 +28,10 @@
#include "gpu_batch_private.hh"
#include "gpu_context_private.hh"
#include "gpu_drawlist_private.hh"
+<<<<<<< HEAD
+=======
+#include "gpu_shader_private.hh"
+>>>>>>> master
namespace blender {
namespace gpu {
@@ -43,7 +47,7 @@ class GPUBackend {
virtual Batch *batch_alloc(void) = 0;
virtual DrawList *drawlist_alloc(int list_length) = 0;
// virtual FrameBuffer *framebuffer_alloc(void) = 0;
- // virtual Shader *shader_alloc(void) = 0;
+ virtual Shader *shader_alloc(const char *name) = 0;
// virtual Texture *texture_alloc(void) = 0;
};
diff --git a/source/blender/gpu/intern/gpu_batch.cc b/source/blender/gpu/intern/gpu_batch.cc
index 7b006bdc6c2..36f60c3dcc8 100644
--- a/source/blender/gpu/intern/gpu_batch.cc
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -39,7 +39,7 @@
#include "gpu_batch_private.hh"
#include "gpu_context_private.hh"
#include "gpu_primitive_private.h"
-#include "gpu_shader_private.h"
+#include "gpu_shader_private.hh"
#include "gpu_vertex_format_private.h"
#include <limits.h>
@@ -176,8 +176,7 @@ int GPU_batch_instbuf_add_ex(GPUBatch *batch, GPUVertBuf *insts, bool own_vbo)
if (batch->inst[v] == NULL) {
/* for now all VertexBuffers must have same vertex_len */
if (batch->inst[0]) {
- /* Allow for different size of vertex buf (will choose the smallest
- * number of verts). */
+ /* Allow for different size of vertex buffer (will choose the smallest number of verts). */
// BLI_assert(insts->vertex_len == batch->inst[0]->vertex_len);
}
@@ -227,87 +226,6 @@ void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader)
GPU_shader_bind(batch->shader);
}
-#define GET_UNIFORM \
- const GPUShaderInput *uniform = GPU_shaderinterface_uniform(batch->shader->interface, name); \
- BLI_assert(uniform);
-
-void GPU_batch_uniform_1i(GPUBatch *batch, const char *name, int value)
-{
- GET_UNIFORM
- GPU_shader_uniform_int(batch->shader, uniform->location, value);
-}
-
-void GPU_batch_uniform_1b(GPUBatch *batch, const char *name, bool value)
-{
- GPU_batch_uniform_1i(batch, name, value ? GL_TRUE : GL_FALSE);
-}
-
-void GPU_batch_uniform_2f(GPUBatch *batch, const char *name, float x, float y)
-{
- const float data[2] = {x, y};
- GPU_batch_uniform_2fv(batch, name, data);
-}
-
-void GPU_batch_uniform_3f(GPUBatch *batch, const char *name, float x, float y, float z)
-{
- const float data[3] = {x, y, z};
- GPU_batch_uniform_3fv(batch, name, data);
-}
-
-void GPU_batch_uniform_4f(GPUBatch *batch, const char *name, float x, float y, float z, float w)
-{
- const float data[4] = {x, y, z, w};
- GPU_batch_uniform_4fv(batch, name, data);
-}
-
-void GPU_batch_uniform_1f(GPUBatch *batch, const char *name, float x)
-{
- GET_UNIFORM
- GPU_shader_uniform_float(batch->shader, uniform->location, x);
-}
-
-void GPU_batch_uniform_2fv(GPUBatch *batch, const char *name, const float data[2])
-{
- GET_UNIFORM
- GPU_shader_uniform_vector(batch->shader, uniform->location, 2, 1, data);
-}
-
-void GPU_batch_uniform_3fv(GPUBatch *batch, const char *name, const float data[3])
-{
- GET_UNIFORM
- GPU_shader_uniform_vector(batch->shader, uniform->location, 3, 1, data);
-}
-
-void GPU_batch_uniform_4fv(GPUBatch *batch, const char *name, const float data[4])
-{
- GET_UNIFORM
- GPU_shader_uniform_vector(batch->shader, uniform->location, 4, 1, data);
-}
-
-void GPU_batch_uniform_2fv_array(GPUBatch *batch,
- const char *name,
- const int len,
- const float *data)
-{
- GET_UNIFORM
- GPU_shader_uniform_vector(batch->shader, uniform->location, 2, len, data);
-}
-
-void GPU_batch_uniform_4fv_array(GPUBatch *batch,
- const char *name,
- const int len,
- const float *data)
-{
- GET_UNIFORM
- GPU_shader_uniform_vector(batch->shader, uniform->location, 4, len, data);
-}
-
-void GPU_batch_uniform_mat4(GPUBatch *batch, const char *name, const float data[4][4])
-{
- GET_UNIFORM
- GPU_shader_uniform_vector(batch->shader, uniform->location, 16, 1, (const float *)data);
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -364,6 +282,8 @@ void GPU_batch_draw_advanced(GPUBatch *batch, int v_first, int v_count, int i_fi
/* just draw some vertices and let shader place them where we want. */
void GPU_draw_primitive(GPUPrimType prim_type, int v_count)
{
+ GPU_context_active_get()->state_manager->apply_state();
+
/* we cannot draw without vao ... annoying ... */
glBindVertexArray(GPU_vao_default());
diff --git a/source/blender/gpu/intern/gpu_batch_presets.c b/source/blender/gpu/intern/gpu_batch_presets.c
index 71c971d8656..8adb1ba1ed3 100644
--- a/source/blender/gpu/intern/gpu_batch_presets.c
+++ b/source/blender/gpu/intern/gpu_batch_presets.c
@@ -35,7 +35,6 @@
#include "GPU_batch.h"
#include "GPU_batch_presets.h" /* own include */
#include "GPU_batch_utils.h"
-#include "gpu_shader_private.h"
/* -------------------------------------------------------------------- */
/** \name Local Structures
diff --git a/source/blender/gpu/intern/gpu_batch_utils.c b/source/blender/gpu/intern/gpu_batch_utils.c
index 0660d4a1724..e2d03d27035 100644
--- a/source/blender/gpu/intern/gpu_batch_utils.c
+++ b/source/blender/gpu/intern/gpu_batch_utils.c
@@ -28,7 +28,6 @@
#include "GPU_batch.h"
#include "GPU_batch_utils.h" /* own include */
-#include "gpu_shader_private.h"
/* -------------------------------------------------------------------- */
/** \name Polygon Creation (2D)
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index e04631910c1..ef02ec24a00 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -70,6 +70,7 @@ GPUContext::GPUContext()
GPUContext::~GPUContext()
{
GPU_matrix_state_discard(matrix_state);
+ delete state_manager;
}
bool GPUContext::is_active_on_thread(void)
diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh
index 3f9fca16ff7..b774d6b0995 100644
--- a/source/blender/gpu/intern/gpu_context_private.hh
+++ b/source/blender/gpu/intern/gpu_context_private.hh
@@ -29,6 +29,8 @@
#include "GPU_context.h"
+#include "gpu_state_private.hh"
+
#include <mutex>
#include <pthread.h>
#include <string.h>
@@ -44,6 +46,7 @@ struct GPUContext {
GPUShader *shader = NULL;
GPUFrameBuffer *current_fbo = NULL;
GPUMatrixState *matrix_state = NULL;
+ blender::gpu::GPUStateManager *state_manager = NULL;
protected:
/** Thread on which this context is active. */
diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc
index 5f3089b2ffb..da8ab80b347 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.cc
+++ b/source/blender/gpu/intern/gpu_framebuffer.cc
@@ -552,7 +552,19 @@ void GPU_framebuffer_bind(GPUFrameBuffer *fb)
}
#endif
- glViewport(0, 0, fb->width, fb->height);
+ GPU_viewport(0, 0, fb->width, fb->height);
+}
+
+/* Workaround for binding a srgb framebuffer without doing the srgb transform. */
+void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *fb)
+{
+ GPU_framebuffer_bind(fb);
+
+ glDisable(GL_FRAMEBUFFER_SRGB);
+
+ GPUTexture *first_target = fb->attachments[GPU_FB_COLOR_ATTACHMENT0].tex;
+ const bool is_srgb_target = (first_target && (GPU_texture_format(first_target) == GPU_SRGB8_A8));
+ GPU_shader_set_framebuffer_srgb_target(!is_srgb_target);
}
void GPU_framebuffer_restore(void)
@@ -599,7 +611,7 @@ void GPU_framebuffer_viewport_set(GPUFrameBuffer *fb, int x, int y, int w, int h
{
CHECK_FRAMEBUFFER_IS_BOUND(fb);
- glViewport(x, y, w, h);
+ GPU_viewport(x, y, w, h);
}
void GPU_framebuffer_clear(GPUFrameBuffer *fb,
@@ -610,6 +622,8 @@ void GPU_framebuffer_clear(GPUFrameBuffer *fb,
{
CHECK_FRAMEBUFFER_IS_BOUND(fb);
+ GPU_context_active_get()->state_manager->apply_state();
+
if (buffers & GPU_COLOR_BIT) {
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glClearColor(clear_col[0], clear_col[1], clear_col[2], clear_col[3]);
@@ -774,6 +788,8 @@ void GPU_framebuffer_blit(GPUFrameBuffer *fb_read,
GLbitfield mask = convert_buffer_bits_to_gl(blit_buffers);
+ GPU_context_active_get()->state_manager->apply_state();
+
glBlitFramebuffer(0,
0,
fb_read->width,
@@ -850,7 +866,7 @@ void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb,
BLI_assert(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER));
- glViewport(0, 0, current_dim[0], current_dim[1]);
+ GPU_viewport(0, 0, current_dim[0], current_dim[1]);
callback(userData, i);
if (current_dim[0] == 1 && current_dim[1] == 1) {
@@ -889,6 +905,13 @@ struct GPUOffScreen {
GPUTexture *color;
GPUTexture *depth;
+
+ /** Saved state of the previously bound framebuffer. */
+ /* TODO(fclem) This is quite hacky and a proper fix would be to
+ * put these states directly inside the GPUFrambuffer.
+ * But we don't have a GPUFramebuffer for the default framebuffer yet. */
+ int saved_viewport[4];
+ int saved_scissor[4];
};
/* Returns the correct framebuffer for the current context. */
@@ -952,21 +975,19 @@ GPUOffScreen *GPU_offscreen_create(
return NULL;
}
- gpuPushAttr(GPU_VIEWPORT_BIT);
+ int viewport[4];
+ GPU_viewport_size_get_i(viewport);
GPUFrameBuffer *fb = gpu_offscreen_fb_get(ofs);
/* check validity at the very end! */
if (!GPU_framebuffer_check_valid(fb, err_out)) {
GPU_offscreen_free(ofs);
- gpuPopAttr();
+ GPU_viewport(UNPACK4(viewport));
return NULL;
}
-
GPU_framebuffer_restore();
-
- gpuPopAttr();
-
+ GPU_viewport(UNPACK4(viewport));
return ofs;
}
@@ -990,7 +1011,9 @@ void GPU_offscreen_free(GPUOffScreen *ofs)
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
{
if (save) {
- gpuPushAttr((eGPUAttrMask)(GPU_SCISSOR_BIT | GPU_VIEWPORT_BIT));
+ GPU_scissor_get(ofs->saved_scissor);
+ GPU_viewport_size_get_i(ofs->saved_viewport);
+
GPUFrameBuffer *fb = GPU_framebuffer_active_get();
gpuPushFrameBuffer(fb);
}
@@ -1001,12 +1024,13 @@ void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
GPU_shader_set_framebuffer_srgb_target(false);
}
-void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore)
+void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore)
{
GPUFrameBuffer *fb = NULL;
if (restore) {
- gpuPopAttr();
+ GPU_scissor(UNPACK4(ofs->saved_scissor));
+ GPU_viewport(UNPACK4(ofs->saved_viewport));
fb = gpuPopFrameBuffer();
}
@@ -1023,6 +1047,8 @@ void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y)
const int w = GPU_texture_width(ofs->color);
const int h = GPU_texture_height(ofs->color);
+ GPU_context_active_get()->state_manager->apply_state();
+
GPUFrameBuffer *ofs_fb = gpu_offscreen_fb_get(ofs);
glBindFramebuffer(GL_READ_FRAMEBUFFER, ofs_fb->object);
@@ -1087,6 +1113,7 @@ void GPU_clear_depth(float depth)
void GPU_clear(eGPUFrameBufferBits flags)
{
+ GPU_context_active_get()->state_manager->apply_state();
glClear(convert_buffer_bits_to_gl(flags));
}
diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc
index 2d137c2f21c..dd05689d69a 100644
--- a/source/blender/gpu/intern/gpu_immediate.cc
+++ b/source/blender/gpu/intern/gpu_immediate.cc
@@ -35,7 +35,7 @@
#include "gpu_attr_binding_private.h"
#include "gpu_context_private.hh"
#include "gpu_primitive_private.h"
-#include "gpu_shader_private.h"
+#include "gpu_shader_private.hh"
#include "gpu_vertex_format_private.h"
#include <stdlib.h>
@@ -145,10 +145,7 @@ GPUVertFormat *immVertexFormat(void)
void immBindShader(GPUShader *shader)
{
-#if TRUST_NO_ONE
- assert(imm.bound_program == NULL);
- assert(glIsProgram(shader->program));
-#endif
+ BLI_assert(imm.bound_program == NULL);
imm.bound_program = shader;
imm.shader_interface = shader->interface;
@@ -159,8 +156,8 @@ void immBindShader(GPUShader *shader)
GPU_shader_bind(shader);
get_attr_locations(&imm.vertex_format, &imm.attr_binding, imm.shader_interface);
- GPU_matrix_bind(imm.shader_interface);
- GPU_shader_set_srgb_uniform(imm.shader_interface);
+ GPU_matrix_bind(shader);
+ GPU_shader_set_srgb_uniform(shader);
}
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
@@ -213,6 +210,8 @@ static bool vertex_count_makes_sense_for_primitive(uint vertex_len, GPUPrimType
void immBegin(GPUPrimType prim_type, uint vertex_len)
{
+ GPU_context_active_get()->state_manager->apply_state();
+
#if TRUST_NO_ONE
assert(initialized);
assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */
@@ -375,7 +374,7 @@ static void immDrawSetup(void)
}
if (GPU_matrix_dirty_get()) {
- GPU_matrix_bind(imm.shader_interface);
+ GPU_matrix_bind(imm.bound_program);
}
}
diff --git a/source/blender/gpu/intern/gpu_matrix.cc b/source/blender/gpu/intern/gpu_matrix.cc
index 5d8d77bbf1c..951652b9393 100644
--- a/source/blender/gpu/intern/gpu_matrix.cc
+++ b/source/blender/gpu/intern/gpu_matrix.cc
@@ -643,13 +643,13 @@ const float (*GPU_matrix_normal_inverse_get(float m[3][3]))[3]
return m;
}
-void GPU_matrix_bind(const GPUShaderInterface *shaderface)
+void GPU_matrix_bind(GPUShader *shader)
{
/* set uniform values to matrix stack values
* call this before a draw call if desired matrices are dirty
* call glUseProgram before this, as glUniform expects program to be bound
*/
-
+ const GPUShaderInterface *shaderface = shader->interface;
int32_t MV = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW);
int32_t P = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION);
int32_t MVP = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MVP);
@@ -658,32 +658,30 @@ void GPU_matrix_bind(const GPUShaderInterface *shaderface)
int32_t MV_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW_INV);
int32_t P_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION_INV);
- /* XXX(fclem) this works but this assumes shader is unused inside GPU_shader_uniform_vector. */
- GPUShader *sh = NULL;
if (MV != -1) {
- GPU_shader_uniform_vector(sh, MV, 16, 1, (const float *)GPU_matrix_model_view_get(NULL));
+ GPU_shader_uniform_vector(shader, MV, 16, 1, (const float *)GPU_matrix_model_view_get(NULL));
}
if (P != -1) {
- GPU_shader_uniform_vector(sh, P, 16, 1, (const float *)GPU_matrix_projection_get(NULL));
+ GPU_shader_uniform_vector(shader, P, 16, 1, (const float *)GPU_matrix_projection_get(NULL));
}
if (MVP != -1) {
GPU_shader_uniform_vector(
- sh, MVP, 16, 1, (const float *)GPU_matrix_model_view_projection_get(NULL));
+ shader, MVP, 16, 1, (const float *)GPU_matrix_model_view_projection_get(NULL));
}
if (N != -1) {
- GPU_shader_uniform_vector(sh, N, 9, 1, (const float *)GPU_matrix_normal_get(NULL));
+ GPU_shader_uniform_vector(shader, N, 9, 1, (const float *)GPU_matrix_normal_get(NULL));
}
if (MV_inv != -1) {
Mat4 m;
GPU_matrix_model_view_get(m);
invert_m4(m);
- GPU_shader_uniform_vector(sh, MV_inv, 16, 1, (const float *)m);
+ GPU_shader_uniform_vector(shader, MV_inv, 16, 1, (const float *)m);
}
if (P_inv != -1) {
Mat4 m;
GPU_matrix_projection_get(m);
invert_m4(m);
- GPU_shader_uniform_vector(sh, P_inv, 16, 1, (const float *)m);
+ GPU_shader_uniform_vector(shader, P_inv, 16, 1, (const float *)m);
}
gpu_matrix_state_active_set_dirty(false);
@@ -734,8 +732,8 @@ float GPU_polygon_offset_calc(const float (*winmat)[4], float viewdist, float di
#else
static float depth_fac = 0.0f;
if (depth_fac == 0.0f) {
- int depthbits;
- glGetIntegerv(GL_DEPTH_BITS, &depthbits);
+ /* Hardcode for 24 bit precision. */
+ int depthbits = 24;
depth_fac = 1.0f / (float)((1 << depthbits) - 1);
}
offs = (-1.0 / winmat[2][2]) * dist * depth_fac;
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index 0f6f29fab40..29e2615345c 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -282,6 +282,12 @@ typedef struct GPUPickState {
uint *rect_id;
} nearest;
};
+
+ /* Previous state to restore after drawing. */
+ int viewport[4];
+ int scissor[4];
+ eGPUWriteMask write_mask;
+ bool depth_test;
} GPUPickState;
static GPUPickState g_pick_state = {0};
@@ -304,7 +310,9 @@ void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, c
/* Restrict OpenGL operations for when we don't have cache */
if (ps->is_cached == false) {
- gpuPushAttr(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT);
+ ps->write_mask = GPU_write_mask_get();
+ ps->depth_test = GPU_depth_test_enabled();
+ GPU_scissor_get(ps->scissor);
/* disable writing to the framebuffer */
GPU_color_mask(false, false, false, false);
@@ -535,8 +543,9 @@ uint gpu_select_pick_end(void)
/* force finishing last pass */
gpu_select_pick_load_id(ps->gl.prev_id, true);
}
- gpuPopAttr();
- GPU_color_mask(true, true, true, true);
+ GPU_write_mask(ps->write_mask);
+ GPU_depth_test(ps->depth_test);
+ GPU_viewport(UNPACK4(ps->viewport));
}
/* assign but never free directly since it may be in cache */
diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c
index f67c9c36a6b..62414febb44 100644
--- a/source/blender/gpu/intern/gpu_select_sample_query.c
+++ b/source/blender/gpu/intern/gpu_select_sample_query.c
@@ -60,6 +60,12 @@ typedef struct GPUQueryState {
char mode;
uint index;
int oldhits;
+
+ /* Previous state to restore after drawing. */
+ int viewport[4];
+ int scissor[4];
+ eGPUWriteMask write_mask;
+ bool depth_test;
} GPUQueryState;
static GPUQueryState g_query_state = {0};
@@ -67,8 +73,6 @@ static GPUQueryState g_query_state = {0};
void gpu_select_query_begin(
uint (*buffer)[4], uint bufsize, const rcti *input, char mode, int oldhits)
{
- float viewport[4];
-
g_query_state.query_issued = false;
g_query_state.active_query = 0;
g_query_state.num_of_queries = 0;
@@ -86,7 +90,10 @@ void gpu_select_query_begin(
"gpu selection ids");
glGenQueries(g_query_state.num_of_queries, g_query_state.queries);
- gpuPushAttr(GPU_DEPTH_BUFFER_BIT | GPU_VIEWPORT_BIT | GPU_SCISSOR_BIT);
+ g_query_state.write_mask = GPU_write_mask_get();
+ g_query_state.depth_test = GPU_depth_test_enabled();
+ GPU_scissor_get(g_query_state.scissor);
+
/* disable writing to the framebuffer */
GPU_color_mask(false, false, false, false);
@@ -94,8 +101,11 @@ void gpu_select_query_begin(
* We need to get the region of the viewport so that our geometry doesn't
* get rejected before the depth test. Should probably cull rect against
* the viewport but this is a rare case I think */
- GPU_viewport_size_get_f(viewport);
- GPU_viewport(viewport[0], viewport[1], BLI_rcti_size_x(input), BLI_rcti_size_y(input));
+ GPU_viewport_size_get_i(g_query_state.viewport);
+ GPU_viewport(g_query_state.viewport[0],
+ g_query_state.viewport[1],
+ BLI_rcti_size_x(input),
+ BLI_rcti_size_y(input));
/* occlusion queries operates on fragments that pass tests and since we are interested on all
* objects in the view frustum independently of their order, we need to disable the depth test */
@@ -204,8 +214,10 @@ uint gpu_select_query_end(void)
glDeleteQueries(g_query_state.num_of_queries, g_query_state.queries);
MEM_freeN(g_query_state.queries);
MEM_freeN(g_query_state.id);
- gpuPopAttr();
- GPU_color_mask(true, true, true, true);
+
+ GPU_write_mask(g_query_state.write_mask);
+ GPU_depth_test(g_query_state.depth_test);
+ GPU_viewport(UNPACK4(g_query_state.viewport));
return hits;
}
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index 7a44efce7fb..536396ad3c6 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -29,6 +29,7 @@
#include "BLI_string.h"
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
+#include "BLI_vector.hh"
#include "BKE_appdir.h"
#include "BKE_global.h"
@@ -42,226 +43,198 @@
#include "GPU_texture.h"
#include "GPU_uniformbuffer.h"
+#include "gpu_backend.hh"
#include "gpu_context_private.hh"
-#include "gpu_shader_private.h"
+#include "gpu_shader_private.hh"
extern "C" char datatoc_gpu_shader_colorspace_lib_glsl[];
-/* Adjust these constants as needed. */
-#define MAX_DEFINE_LENGTH 256
-#define MAX_EXT_DEFINE_LENGTH 512
-
-#ifndef NDEBUG
-static uint g_shaderid = 0;
-#endif
+using namespace blender;
+using namespace blender::gpu;
/* -------------------------------------------------------------------- */
-/** \name Convenience functions
+/** \name Debug functions
* \{ */
-static void shader_print_errors(const char *task, const char *log, const char **code, int totcode)
+void Shader::print_errors(Span<const char *> sources, char *log)
{
- int line = 1;
-
- fprintf(stderr, "GPUShader: %s error:\n", task);
-
- for (int i = 0; i < totcode; i++) {
- const char *c, *pos, *end = code[i] + strlen(code[i]);
-
- if (G.debug & G_DEBUG) {
- fprintf(stderr, "===== shader string %d ====\n", i + 1);
+ const bool pretty = true;
+ const char line_prefix[] = " | ";
+ char *sources_combined = BLI_string_join_arrayN((const char **)sources.data(), sources.size());
- c = code[i];
- while ((c < end) && (pos = strchr(c, '\n'))) {
- fprintf(stderr, "%2d ", line);
- fwrite(c, (pos + 1) - c, 1, stderr);
- c = pos + 1;
- line++;
+ if (pretty) {
+ fprintf(stderr, "\n \033[1mShader Compilation Log : \033[0m%s\n", this->name);
+ }
+ else {
+ fprintf(stderr, "\n Shader Compilation Log : %s\n", this->name);
+ }
+
+ char *log_line = log, *line_end;
+ char *error_line_number_end;
+ int error_line, error_char, last_error_line = -2, last_error_char = -1;
+ bool found_line_id = false;
+ while ((line_end = strchr(log_line, '\n'))) {
+ /* Skip empty lines. */
+ if (line_end == log_line) {
+ log_line++;
+ continue;
+ }
+ /* Skip ERROR: or WARNING:. */
+ const char *prefix[] = {"ERROR", "WARNING"};
+ for (int i = 0; i < ARRAY_SIZE(prefix); i++) {
+ if (STREQLEN(log_line, prefix[i], strlen(prefix[i]))) {
+ log_line += strlen(prefix[i]);
+ break;
}
-
- fprintf(stderr, "%s", c);
}
+ error_line = error_char = -1;
+ if (ELEM(log_line[0], '0', ':') && ELEM(log_line[1], ':', '(', ' ')) {
+ error_line = (int)strtol(log_line + 2, &error_line_number_end, 10);
+ /* Try to fetch the error caracter (not always available). */
+ if (ELEM(error_line_number_end[0], '(', ':')) {
+ error_char = (int)strtol(error_line_number_end + 1, NULL, 10);
+ }
+ }
+ if (error_line == -1) {
+ found_line_id = false;
+ }
+ const char *src_line = sources_combined;
+ /* Some drivers use (source:line) instead of (line:char) */
+ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OFFICIAL) && (error_line != -1) &&
+ (error_char != -1)) {
+ int error_source = error_line;
+ if (error_source < sources.size()) {
+ src_line = sources[error_source];
+ error_line = error_char;
+ error_char = -1;
+ }
+ }
+ /* Separate from previous block. */
+ if (last_error_line != error_line) {
+ fprintf(stderr, "\n");
+ }
+ /* Print line from the source file that is producing the error. */
+ if ((error_line != -1) && (error_line != last_error_line || error_char != last_error_char)) {
+ const char *src_line_end = src_line;
+ found_line_id = false;
+ /* error_line is 1 based in this case. */
+ int src_line_index = 1;
+ while ((src_line_end = strchr(src_line, '\n'))) {
+ if (src_line_index == error_line) {
+ found_line_id = true;
+ break;
+ }
+ /* Continue to next line. */
+ src_line = src_line_end + 1;
+ src_line_index++;
+ }
+ /* Print error source. */
+ if (found_line_id) {
+ fprintf(stderr, "%5d | ", src_line_index);
+ fwrite(src_line, (src_line_end + 1) - src_line, 1, stderr);
+ /* Print char offset. */
+ fprintf(stderr, line_prefix);
+ if (error_char != -1) {
+ for (int i = 0; i < error_char; i++) {
+ fprintf(stderr, " ");
+ }
+ fprintf(stderr, "^");
+ }
+ fprintf(stderr, "\n");
+ }
+ }
+ fprintf(stderr, line_prefix);
+ if (found_line_id) {
+ /* Skip to message. Avoid redundant info. */
+ const char *keywords[] = {"error", "warning"};
+ for (int i = 0; i < ARRAY_SIZE(keywords); i++) {
+ /* Avoid searching following lines. */
+ line_end[0] = '\0';
+ if (strstr(log_line, keywords[i])) {
+ log_line = strstr(log_line, keywords[i]);
+ if (pretty) {
+ if (STREQ(keywords[i], "error")) {
+ fprintf(stderr, "\033[31;1mError\033[0m ");
+ }
+ else if (STREQ(keywords[i], "warning")) {
+ fprintf(stderr, "\033[33;1mWarning\033[0m ");
+ }
+ log_line += strlen(keywords[i]);
+ }
+ break;
+ }
+ }
+ line_end[0] = '\n';
+ }
+ /* Print the error itself. */
+ if (pretty) {
+ fprintf(stderr, "\033[2m");
+ }
+ fwrite(log_line, (line_end + 1) - log_line, 1, stderr);
+ if (pretty) {
+ fprintf(stderr, "\033[0m");
+ }
+ /* Continue to next line. */
+ log_line = line_end + 1;
+ last_error_line = error_line;
+ last_error_char = error_char;
}
-
- fprintf(stderr, "%s\n", log);
+ fprintf(stderr, "\n\n");
+ MEM_freeN(sources_combined);
}
-static const char *gpu_shader_version(void)
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Creation / Destruction
+ * \{ */
+
+Shader::Shader(const char *sh_name)
{
- return "#version 330\n";
+ BLI_strncpy(this->name, sh_name, sizeof(this->name));
}
-static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH])
+Shader::~Shader()
{
- /* enable extensions for features that are not part of our base GLSL version
- * don't use an extension for something already available!
- */
-
- if (GLEW_ARB_texture_gather) {
- /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather
- * is reported to be supported but yield a compile error (see T55802). */
- if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) || GLEW_VERSION_4_0) {
- strcat(defines, "#extension GL_ARB_texture_gather: enable\n");
-
- /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the
- * shader so double check the preprocessor define (see T56544). */
- if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) {
- strcat(defines, "#ifdef GL_ARB_texture_gather\n");
- strcat(defines, "# define GPU_ARB_texture_gather\n");
- strcat(defines, "#endif\n");
- }
- else {
- strcat(defines, "#define GPU_ARB_texture_gather\n");
- }
- }
- }
- if (GLEW_ARB_texture_query_lod) {
- /* a #version 400 feature, but we use #version 330 maximum so use extension */
- strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
- }
- if (GLEW_ARB_shader_draw_parameters) {
- strcat(defines, "#extension GL_ARB_shader_draw_parameters : enable\n");
- strcat(defines, "#define GPU_ARB_shader_draw_parameters\n");
- }
- if (GPU_arb_texture_cube_map_array_is_supported()) {
- strcat(defines, "#extension GL_ARB_texture_cube_map_array : enable\n");
- strcat(defines, "#define GPU_ARB_texture_cube_map_array\n");
+ if (this->interface) {
+ GPU_shaderinterface_discard(this->interface);
}
}
-static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
+static void standard_defines(Vector<const char *> &sources)
{
+ BLI_assert(sources.size() == 0);
+ /* Version needs to be first. Exact values will be added by implementation. */
+ sources.append("version");
/* some useful defines to detect GPU type */
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- strcat(defines, "#define GPU_ATI\n");
- if (GPU_crappy_amd_driver()) {
- strcat(defines, "#define GPU_DEPRECATED_AMD_DRIVER\n");
- }
+ sources.append("#define GPU_ATI\n");
}
else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- strcat(defines, "#define GPU_NVIDIA\n");
+ sources.append("#define GPU_NVIDIA\n");
}
else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- strcat(defines, "#define GPU_INTEL\n");
+ sources.append("#define GPU_INTEL\n");
}
-
/* some useful defines to detect OS type */
if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_WIN, GPU_DRIVER_ANY)) {
- strcat(defines, "#define OS_WIN\n");
+ sources.append("#define OS_WIN\n");
}
else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) {
- strcat(defines, "#define OS_MAC\n");
+ sources.append("#define OS_MAC\n");
}
else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_UNIX, GPU_DRIVER_ANY)) {
- strcat(defines, "#define OS_UNIX\n");
- }
-
- float derivatives_factors[2];
- GPU_get_dfdy_factors(derivatives_factors);
- if (derivatives_factors[0] == 1.0f) {
- strcat(defines, "#define DFDX_SIGN 1.0\n");
- }
- else {
- strcat(defines, "#define DFDX_SIGN -1.0\n");
- }
-
- if (derivatives_factors[1] == 1.0f) {
- strcat(defines, "#define DFDY_SIGN 1.0\n");
- }
- else {
- strcat(defines, "#define DFDY_SIGN -1.0\n");
- }
-}
-
-#define DEBUG_SHADER_NONE ""
-#define DEBUG_SHADER_VERTEX "vert"
-#define DEBUG_SHADER_FRAGMENT "frag"
-#define DEBUG_SHADER_GEOMETRY "geom"
-
-/**
- * Dump GLSL shaders to disk
- *
- * This is used for profiling shader performance externally and debug if shader code is correct.
- * If called with no code, it simply bumps the shader index, so different shaders for the same
- * program share the same index.
- */
-static void gpu_dump_shaders(const char **code, const int num_shaders, const char *extension)
-{
- if ((G.debug & G_DEBUG_GPU_SHADERS) == 0) {
- return;
+ sources.append("#define OS_UNIX\n");
}
- /* We use the same shader index for shaders in the same program.
- * So we call this function once before calling for the individual shaders. */
- static int shader_index = 0;
- if (code == NULL) {
- shader_index++;
- BLI_assert(STREQ(DEBUG_SHADER_NONE, extension));
- return;
+ if (GPU_crappy_amd_driver()) {
+ sources.append("#define GPU_DEPRECATED_AMD_DRIVER\n");
}
-
- /* Determine the full path of the new shader. */
- char shader_path[FILE_MAX];
-
- char file_name[512] = {'\0'};
- sprintf(file_name, "%04d.%s", shader_index, extension);
-
- BLI_join_dirfile(shader_path, sizeof(shader_path), BKE_tempdir_session(), file_name);
-
- /* Write shader to disk. */
- FILE *f = fopen(shader_path, "w");
- if (f == NULL) {
- printf("Error writing to file: %s\n", shader_path);
- }
- for (int j = 0; j < num_shaders; j++) {
- fprintf(f, "%s", code[j]);
- }
- fclose(f);
- printf("Shader file written to disk: %s\n", shader_path);
}
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Creation / Destruction
- * \{ */
-
-GPUShader *GPU_shader_create(const char *vertexcode,
- const char *fragcode,
- const char *geocode,
- const char *libcode,
- const char *defines,
- const char *shname)
-{
- return GPU_shader_create_ex(
- vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, shname);
-}
-
-GPUShader *GPU_shader_create_from_python(const char *vertexcode,
- const char *fragcode,
- const char *geocode,
- const char *libcode,
- const char *defines)
-{
- char *libcodecat = NULL;
-
- if (libcode == NULL) {
- libcode = datatoc_gpu_shader_colorspace_lib_glsl;
- }
- else {
- libcode = libcodecat = BLI_strdupcat(libcode, datatoc_gpu_shader_colorspace_lib_glsl);
- }
-
- GPUShader *sh = GPU_shader_create_ex(
- vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, NULL);
-
- MEM_SAFE_FREE(libcodecat);
- return sh;
-}
-
-GPUShader *GPU_shader_create_ex(const char *vertexcode,
+GPUShader *GPU_shader_create_ex(const char *vertcode,
const char *fragcode,
- const char *geocode,
+ const char *geomcode,
const char *libcode,
const char *defines,
const eGPUShaderTFBType tf_type,
@@ -269,223 +242,113 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode,
const int tf_count,
const char *shname)
{
- GLint status;
- GLchar log[5000];
- GLsizei length = 0;
- GPUShader *shader;
- char standard_defines[MAX_DEFINE_LENGTH] = "";
- char standard_extensions[MAX_EXT_DEFINE_LENGTH] = "";
-
- shader = (GPUShader *)MEM_callocN(sizeof(GPUShader), "GPUShader");
- gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE);
-
-#ifndef NDEBUG
- BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++);
-#else
- UNUSED_VARS(shname);
-#endif
-
/* At least a vertex shader and a fragment shader are required. */
- BLI_assert((fragcode != NULL) && (vertexcode != NULL));
+ BLI_assert((fragcode != NULL) && (vertcode != NULL));
- if (vertexcode) {
- shader->vertex = glCreateShader(GL_VERTEX_SHADER);
- }
- if (fragcode) {
- shader->fragment = glCreateShader(GL_FRAGMENT_SHADER);
- }
- if (geocode) {
- shader->geometry = glCreateShader(GL_GEOMETRY_SHADER);
- }
-
- shader->program = glCreateProgram();
-
- if (!shader->program || (vertexcode && !shader->vertex) || (fragcode && !shader->fragment) ||
- (geocode && !shader->geometry)) {
- fprintf(stderr, "GPUShader, object creation failed.\n");
- GPU_shader_free(shader);
- return NULL;
- }
+ Shader *shader = GPUBackend::get()->shader_alloc(shname);
- gpu_shader_standard_defines(standard_defines);
- gpu_shader_standard_extensions(standard_extensions);
-
- if (vertexcode) {
- const char *source[7];
- /* custom limit, may be too small, beware */
- int num_source = 0;
-
- source[num_source++] = gpu_shader_version();
- source[num_source++] =
- "#define GPU_VERTEX_SHADER\n"
- "#define IN_OUT out\n";
- source[num_source++] = standard_extensions;
- source[num_source++] = standard_defines;
-
- if (geocode) {
- source[num_source++] = "#define USE_GEOMETRY_SHADER\n";
+ if (vertcode) {
+ Vector<const char *> sources;
+ standard_defines(sources);
+ sources.append("#define GPU_VERTEX_SHADER\n");
+ sources.append("#define IN_OUT out\n");
+ if (geomcode) {
+ sources.append("#define USE_GEOMETRY_SHADER\n");
}
if (defines) {
- source[num_source++] = defines;
+ sources.append(defines);
}
- source[num_source++] = vertexcode;
-
- gpu_dump_shaders(source, num_source, DEBUG_SHADER_VERTEX);
-
- glAttachShader(shader->program, shader->vertex);
- glShaderSource(shader->vertex, num_source, source, NULL);
+ sources.append(vertcode);
- glCompileShader(shader->vertex);
- glGetShaderiv(shader->vertex, GL_COMPILE_STATUS, &status);
-
- if (!status) {
- glGetShaderInfoLog(shader->vertex, sizeof(log), &length, log);
- shader_print_errors("compile", log, source, num_source);
-
- GPU_shader_free(shader);
- return NULL;
- }
+ shader->vertex_shader_from_glsl(sources);
}
if (fragcode) {
- const char *source[8];
- int num_source = 0;
-
- source[num_source++] = gpu_shader_version();
- source[num_source++] =
- "#define GPU_FRAGMENT_SHADER\n"
- "#define IN_OUT in\n";
- source[num_source++] = standard_extensions;
- source[num_source++] = standard_defines;
-
- if (geocode) {
- source[num_source++] = "#define USE_GEOMETRY_SHADER\n";
+ Vector<const char *> sources;
+ standard_defines(sources);
+ sources.append("#define GPU_FRAGMENT_SHADER\n");
+ sources.append("#define IN_OUT in\n");
+ if (geomcode) {
+ sources.append("#define USE_GEOMETRY_SHADER\n");
}
if (defines) {
- source[num_source++] = defines;
+ sources.append(defines);
}
if (libcode) {
- source[num_source++] = libcode;
+ sources.append(libcode);
}
- source[num_source++] = fragcode;
-
- gpu_dump_shaders(source, num_source, DEBUG_SHADER_FRAGMENT);
-
- glAttachShader(shader->program, shader->fragment);
- glShaderSource(shader->fragment, num_source, source, NULL);
-
- glCompileShader(shader->fragment);
- glGetShaderiv(shader->fragment, GL_COMPILE_STATUS, &status);
+ sources.append(fragcode);
- if (!status) {
- glGetShaderInfoLog(shader->fragment, sizeof(log), &length, log);
- shader_print_errors("compile", log, source, num_source);
-
- GPU_shader_free(shader);
- return NULL;
- }
+ shader->fragment_shader_from_glsl(sources);
}
- if (geocode) {
- const char *source[6];
- int num_source = 0;
-
- source[num_source++] = gpu_shader_version();
- source[num_source++] = "#define GPU_GEOMETRY_SHADER\n";
- source[num_source++] = standard_extensions;
- source[num_source++] = standard_defines;
-
+ if (geomcode) {
+ Vector<const char *> sources;
+ standard_defines(sources);
+ sources.append("#define GPU_GEOMETRY_SHADER\n");
if (defines) {
- source[num_source++] = defines;
+ sources.append(defines);
}
- source[num_source++] = geocode;
-
- gpu_dump_shaders(source, num_source, DEBUG_SHADER_GEOMETRY);
+ sources.append(geomcode);
- glAttachShader(shader->program, shader->geometry);
- glShaderSource(shader->geometry, num_source, source, NULL);
-
- glCompileShader(shader->geometry);
- glGetShaderiv(shader->geometry, GL_COMPILE_STATUS, &status);
-
- if (!status) {
- glGetShaderInfoLog(shader->geometry, sizeof(log), &length, log);
- shader_print_errors("compile", log, source, num_source);
-
- GPU_shader_free(shader);
- return NULL;
- }
+ shader->geometry_shader_from_glsl(sources);
}
- if (tf_names != NULL) {
- glTransformFeedbackVaryings(shader->program, tf_count, tf_names, GL_INTERLEAVED_ATTRIBS);
- /* Primitive type must be setup */
+ if (tf_names != NULL && tf_count > 0) {
BLI_assert(tf_type != GPU_SHADER_TFB_NONE);
- shader->feedback_transform_type = tf_type;
+ shader->transform_feedback_names_set(Span<const char *>(tf_names, tf_count), tf_type);
}
- glLinkProgram(shader->program);
- glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
- if (!status) {
- glGetProgramInfoLog(shader->program, sizeof(log), &length, log);
- /* print attached shaders in pipeline order */
- if (defines) {
- shader_print_errors("linking", log, &defines, 1);
- }
- if (vertexcode) {
- shader_print_errors("linking", log, &vertexcode, 1);
- }
- if (geocode) {
- shader_print_errors("linking", log, &geocode, 1);
- }
- if (libcode) {
- shader_print_errors("linking", log, &libcode, 1);
- }
- if (fragcode) {
- shader_print_errors("linking", log, &fragcode, 1);
- }
-
- GPU_shader_free(shader);
+ if (!shader->finalize()) {
+ delete shader;
return NULL;
- }
+ };
- glUseProgram(shader->program);
- shader->interface = GPU_shaderinterface_create(shader->program);
+ return static_cast<GPUShader *>(shader);
+}
- return shader;
+void GPU_shader_free(GPUShader *shader)
+{
+ delete static_cast<Shader *>(shader);
}
-#undef DEBUG_SHADER_GEOMETRY
-#undef DEBUG_SHADER_FRAGMENT
-#undef DEBUG_SHADER_VERTEX
-#undef DEBUG_SHADER_NONE
+/** \} */
-void GPU_shader_free(GPUShader *shader)
+/* -------------------------------------------------------------------- */
+/** \name Creation utils
+ * \{ */
+
+GPUShader *GPU_shader_create(const char *vertcode,
+ const char *fragcode,
+ const char *geomcode,
+ const char *libcode,
+ const char *defines,
+ const char *shname)
{
-#if 0 /* Would be nice to have, but for now the Deferred compilation \
- * does not have a GPUContext. */
- BLI_assert(GPU_context_active_get() != NULL);
-#endif
- BLI_assert(shader);
+ return GPU_shader_create_ex(
+ vertcode, fragcode, geomcode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, shname);
+}
- if (shader->vertex) {
- glDeleteShader(shader->vertex);
- }
- if (shader->geometry) {
- glDeleteShader(shader->geometry);
- }
- if (shader->fragment) {
- glDeleteShader(shader->fragment);
+GPUShader *GPU_shader_create_from_python(const char *vertcode,
+ const char *fragcode,
+ const char *geomcode,
+ const char *libcode,
+ const char *defines)
+{
+ char *libcodecat = NULL;
+
+ if (libcode == NULL) {
+ libcode = datatoc_gpu_shader_colorspace_lib_glsl;
}
- if (shader->program) {
- glDeleteProgram(shader->program);
+ else {
+ libcode = libcodecat = BLI_strdupcat(libcode, datatoc_gpu_shader_colorspace_lib_glsl);
}
- if (shader->interface) {
- GPU_shaderinterface_discard(shader->interface);
- }
+ GPUShader *sh = GPU_shader_create_ex(
+ vertcode, fragcode, geomcode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, NULL);
- MEM_freeN(shader);
+ MEM_SAFE_FREE(libcodecat);
+ return sh;
}
static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_is_alloc)
@@ -534,7 +397,7 @@ static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_i
* \endcode
*/
struct GPUShader *GPU_shader_create_from_arrays_impl(
- const struct GPU_ShaderCreateFromArray_Params *params)
+ const struct GPU_ShaderCreateFromArray_Params *params, const char *func, int line)
{
struct {
const char *str;
@@ -546,8 +409,11 @@ struct GPUShader *GPU_shader_create_from_arrays_impl(
str_dst[i].str = string_join_array_maybe_alloc(str_src[i], &str_dst[i].is_alloc);
}
+ char name[64];
+ BLI_snprintf(name, sizeof(name), "%s_%d", func, line);
+
GPUShader *sh = GPU_shader_create(
- str_dst[0].str, str_dst[1].str, str_dst[2].str, NULL, str_dst[3].str, __func__);
+ str_dst[0].str, str_dst[1].str, str_dst[2].str, NULL, str_dst[3].str, name);
for (int i = 0; i < ARRAY_SIZE(str_dst); i++) {
if (str_dst[i].is_alloc) {
@@ -563,21 +429,21 @@ struct GPUShader *GPU_shader_create_from_arrays_impl(
/** \name Binding
* \{ */
-void GPU_shader_bind(GPUShader *shader)
+void GPU_shader_bind(GPUShader *gpu_shader)
{
- BLI_assert(shader && shader->program);
+ Shader *shader = static_cast<Shader *>(gpu_shader);
GPUContext *ctx = GPU_context_active_get();
if (ctx->shader != shader) {
ctx->shader = shader;
- glUseProgram(shader->program);
- GPU_matrix_bind(shader->interface);
- GPU_shader_set_srgb_uniform(shader->interface);
+ shader->bind();
+ GPU_matrix_bind(shader);
+ GPU_shader_set_srgb_uniform(shader);
}
if (GPU_matrix_dirty_get()) {
- GPU_matrix_bind(shader->interface);
+ GPU_matrix_bind(shader);
}
}
@@ -585,8 +451,10 @@ void GPU_shader_unbind(void)
{
#ifndef NDEBUG
GPUContext *ctx = GPU_context_active_get();
+ if (ctx->shader) {
+ static_cast<Shader *>(ctx->shader)->unbind();
+ }
ctx->shader = NULL;
- glUseProgram(0);
#endif
}
@@ -594,34 +462,18 @@ void GPU_shader_unbind(void)
/* -------------------------------------------------------------------- */
/** \name Transform feedback
+ *
+ * TODO(fclem) Should be replaced by compute shaders.
* \{ */
-bool GPU_shader_transform_feedback_enable(GPUShader *shader, uint vbo_id)
+bool GPU_shader_transform_feedback_enable(GPUShader *shader, GPUVertBuf *vertbuf)
{
- if (shader->feedback_transform_type == GPU_SHADER_TFB_NONE) {
- return false;
- }
-
- glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo_id);
-
- switch (shader->feedback_transform_type) {
- case GPU_SHADER_TFB_POINTS:
- glBeginTransformFeedback(GL_POINTS);
- return true;
- case GPU_SHADER_TFB_LINES:
- glBeginTransformFeedback(GL_LINES);
- return true;
- case GPU_SHADER_TFB_TRIANGLES:
- glBeginTransformFeedback(GL_TRIANGLES);
- return true;
- default:
- return false;
- }
+ return static_cast<Shader *>(shader)->transform_feedback_enable(vertbuf);
}
-void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader))
+void GPU_shader_transform_feedback_disable(GPUShader *shader)
{
- glEndTransformFeedback();
+ static_cast<Shader *>(shader)->transform_feedback_disable();
}
/** \} */
@@ -632,49 +484,42 @@ void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader))
int GPU_shader_get_uniform(GPUShader *shader, const char *name)
{
- BLI_assert(shader && shader->program);
const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shader->interface, name);
return uniform ? uniform->location : -1;
}
int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
{
- BLI_assert(shader && shader->program);
return GPU_shaderinterface_uniform_builtin(shader->interface,
static_cast<GPUUniformBuiltin>(builtin));
}
int GPU_shader_get_builtin_block(GPUShader *shader, int builtin)
{
- BLI_assert(shader && shader->program);
return GPU_shaderinterface_block_builtin(shader->interface,
static_cast<GPUUniformBlockBuiltin>(builtin));
}
int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
{
- BLI_assert(shader && shader->program);
const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
return ubo ? ubo->location : -1;
}
int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name)
{
- BLI_assert(shader && shader->program);
const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
return ubo ? ubo->binding : -1;
}
int GPU_shader_get_texture_binding(GPUShader *shader, const char *name)
{
- BLI_assert(shader && shader->program);
const GPUShaderInput *tex = GPU_shaderinterface_uniform(shader->interface, name);
return tex ? tex->binding : -1;
}
int GPU_shader_get_attribute(GPUShader *shader, const char *name)
{
- BLI_assert(shader && shader->program);
const GPUShaderInput *attr = GPU_shaderinterface_attr(shader->interface, name);
return attr ? attr->location : -1;
}
@@ -686,9 +531,10 @@ int GPU_shader_get_attribute(GPUShader *shader, const char *name)
* \{ */
/* Clement : Temp */
-int GPU_shader_get_program(GPUShader *shader)
+int GPU_shader_get_program(GPUShader *UNUSED(shader))
{
- return (int)shader->program;
+ /* TODO fixme */
+ return (int)0;
}
/** \} */
@@ -698,57 +544,15 @@ int GPU_shader_get_program(GPUShader *shader)
* \{ */
void GPU_shader_uniform_vector(
- GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value)
+ GPUShader *shader, int loc, int len, int arraysize, const float *value)
{
- if (location == -1 || value == NULL) {
- return;
- }
-
- switch (length) {
- case 1:
- glUniform1fv(location, arraysize, value);
- break;
- case 2:
- glUniform2fv(location, arraysize, value);
- break;
- case 3:
- glUniform3fv(location, arraysize, value);
- break;
- case 4:
- glUniform4fv(location, arraysize, value);
- break;
- case 9:
- glUniformMatrix3fv(location, arraysize, 0, value);
- break;
- case 16:
- glUniformMatrix4fv(location, arraysize, 0, value);
- break;
- default:
- BLI_assert(0);
- break;
- }
+ static_cast<Shader *>(shader)->uniform_float(loc, len, arraysize, value);
}
void GPU_shader_uniform_vector_int(
- GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value)
-{
- switch (length) {
- case 1:
- glUniform1iv(location, arraysize, value);
- break;
- case 2:
- glUniform2iv(location, arraysize, value);
- break;
- case 3:
- glUniform3iv(location, arraysize, value);
- break;
- case 4:
- glUniform4iv(location, arraysize, value);
- break;
- default:
- BLI_assert(0);
- break;
- }
+ GPUShader *shader, int loc, int len, int arraysize, const int *value)
+{
+ static_cast<Shader *>(shader)->uniform_int(loc, len, arraysize, value);
}
void GPU_shader_uniform_int(GPUShader *shader, int location, int value)
@@ -851,11 +655,11 @@ void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, cons
static int g_shader_builtin_srgb_transform = 0;
-void GPU_shader_set_srgb_uniform(const GPUShaderInterface *interface)
+void GPU_shader_set_srgb_uniform(GPUShader *shader)
{
- int32_t loc = GPU_shaderinterface_uniform_builtin(interface, GPU_UNIFORM_SRGB_TRANSFORM);
+ int32_t loc = GPU_shaderinterface_uniform_builtin(shader->interface, GPU_UNIFORM_SRGB_TRANSFORM);
if (loc != -1) {
- glUniform1i(loc, g_shader_builtin_srgb_transform);
+ GPU_shader_uniform_vector_int(shader, loc, 1, 1, &g_shader_builtin_srgb_transform);
}
}
diff --git a/source/blender/gpu/intern/gpu_shader_builtin.c b/source/blender/gpu/intern/gpu_shader_builtin.c
index 9c0692b76e2..da5bcaeca17 100644
--- a/source/blender/gpu/intern/gpu_shader_builtin.c
+++ b/source/blender/gpu/intern/gpu_shader_builtin.c
@@ -42,8 +42,6 @@
#include "GPU_texture.h"
#include "GPU_uniformbuffer.h"
-#include "gpu_shader_private.h"
-
/* Adjust these constants as needed. */
#define MAX_DEFINE_LENGTH 256
#define MAX_EXT_DEFINE_LENGTH 512
diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh
new file mode 100644
index 00000000000..1f667fb4cf9
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_shader_private.hh
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "BLI_span.hh"
+
+#include "GPU_shader.h"
+#include "GPU_shader_interface.h"
+#include "GPU_vertex_buffer.h"
+
+namespace blender {
+namespace gpu {
+
+class Shader : public GPUShader {
+ public:
+ Shader(const char *name);
+ virtual ~Shader();
+
+ virtual void vertex_shader_from_glsl(MutableSpan<const char *> sources) = 0;
+ virtual void geometry_shader_from_glsl(MutableSpan<const char *> sources) = 0;
+ virtual void fragment_shader_from_glsl(MutableSpan<const char *> sources) = 0;
+ virtual bool finalize(void) = 0;
+
+ virtual void transform_feedback_names_set(Span<const char *> name_list,
+ const eGPUShaderTFBType geom_type) = 0;
+ virtual bool transform_feedback_enable(GPUVertBuf *) = 0;
+ virtual void transform_feedback_disable(void) = 0;
+
+ virtual void bind(void) = 0;
+ virtual void unbind(void) = 0;
+
+ virtual void uniform_float(int location, int comp_len, int array_size, const float *data) = 0;
+ virtual void uniform_int(int location, int comp_len, int array_size, const int *data) = 0;
+
+ virtual void vertformat_from_shader(GPUVertFormat *) const = 0;
+
+ protected:
+ void print_errors(Span<const char *> sources, char *log);
+};
+
+} // namespace gpu
+} // namespace blender
+
+/* XXX do not use it. Special hack to use OCIO with batch API. */
+GPUShader *immGetShader(void);
diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc
index 794c7a3eb97..f02ec9c5cd4 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -25,6 +25,7 @@
# define PIXELSIZE (1.0f)
#endif
+#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
#include "BKE_global.h"
@@ -33,239 +34,242 @@
#include "GPU_glew.h"
#include "GPU_state.h"
-static GLenum gpu_get_gl_blendfunction(eGPUBlendFunction blend)
-{
- switch (blend) {
- case GPU_ONE:
- return GL_ONE;
- case GPU_SRC_ALPHA:
- return GL_SRC_ALPHA;
- case GPU_ONE_MINUS_SRC_ALPHA:
- return GL_ONE_MINUS_SRC_ALPHA;
- case GPU_DST_COLOR:
- return GL_DST_COLOR;
- case GPU_ZERO:
- return GL_ZERO;
- default:
- BLI_assert(!"Unhandled blend mode");
- return GL_ZERO;
- }
-}
+#include "gpu_context_private.hh"
+
+#include "gpu_state_private.hh"
+
+using namespace blender::gpu;
+
+#define SET_STATE(_prefix, _state, _value) \
+ do { \
+ GPUStateManager *stack = GPU_context_active_get()->state_manager; \
+ auto &state_object = stack->_prefix##state; \
+ state_object._state = _value; \
+ } while (0)
-void GPU_blend(bool enable)
+#define SET_IMMUTABLE_STATE(_state, _value) SET_STATE(, _state, _value)
+#define SET_MUTABLE_STATE(_state, _value) SET_STATE(mutable_, _state, _value)
+
+/* -------------------------------------------------------------------- */
+/** \name Immutable state Setters
+ * \{ */
+
+void GPU_blend(eGPUBlend blend)
{
- if (enable) {
- glEnable(GL_BLEND);
- }
- else {
- glDisable(GL_BLEND);
- }
+ SET_IMMUTABLE_STATE(blend, blend);
}
-void GPU_blend_set_func(eGPUBlendFunction sfactor, eGPUBlendFunction dfactor)
+void GPU_face_culling(eGPUFaceCullTest culling)
{
- glBlendFunc(gpu_get_gl_blendfunction(sfactor), gpu_get_gl_blendfunction(dfactor));
+ SET_IMMUTABLE_STATE(culling_test, culling);
}
-void GPU_blend_set_func_separate(eGPUBlendFunction src_rgb,
- eGPUBlendFunction dst_rgb,
- eGPUBlendFunction src_alpha,
- eGPUBlendFunction dst_alpha)
+void GPU_front_facing(bool invert)
{
- glBlendFuncSeparate(gpu_get_gl_blendfunction(src_rgb),
- gpu_get_gl_blendfunction(dst_rgb),
- gpu_get_gl_blendfunction(src_alpha),
- gpu_get_gl_blendfunction(dst_alpha));
+ SET_IMMUTABLE_STATE(invert_facing, invert);
}
-void GPU_face_culling(eGPUFaceCull culling)
+void GPU_provoking_vertex(eGPUProvokingVertex vert)
{
- if (culling == GPU_CULL_NONE) {
- glDisable(GL_CULL_FACE);
- }
- else {
- glEnable(GL_CULL_FACE);
- glCullFace((culling == GPU_CULL_FRONT) ? GL_FRONT : GL_BACK);
- }
+ SET_IMMUTABLE_STATE(provoking_vert, vert);
}
-void GPU_front_facing(bool invert)
+/* TODO explicit depth test. */
+void GPU_depth_test(bool enable)
{
- glFrontFace((invert) ? GL_CW : GL_CCW);
+ SET_IMMUTABLE_STATE(depth_test, (enable) ? GPU_DEPTH_LESS_EQUAL : GPU_DEPTH_NONE);
}
-void GPU_provoking_vertex(eGPUProvokingVertex vert)
+void GPU_line_smooth(bool enable)
{
- glProvokingVertex((vert == GPU_VERTEX_FIRST) ? GL_FIRST_VERTEX_CONVENTION :
- GL_LAST_VERTEX_CONVENTION);
+ SET_IMMUTABLE_STATE(line_smooth, enable);
}
-void GPU_depth_range(float near, float far)
+void GPU_polygon_smooth(bool enable)
{
- /* glDepthRangef is only for OpenGL 4.1 or higher */
- glDepthRange(near, far);
+ SET_IMMUTABLE_STATE(polygon_smooth, enable);
}
-void GPU_depth_test(bool enable)
+void GPU_logic_op_xor_set(bool enable)
{
- if (enable) {
- glEnable(GL_DEPTH_TEST);
- }
- else {
- glDisable(GL_DEPTH_TEST);
- }
+ SET_IMMUTABLE_STATE(logic_op_xor, enable);
}
-bool GPU_depth_test_enabled()
+void GPU_write_mask(eGPUWriteMask mask)
{
- return glIsEnabled(GL_DEPTH_TEST);
+ SET_IMMUTABLE_STATE(write_mask, mask);
}
-void GPU_line_smooth(bool enable)
+void GPU_color_mask(bool r, bool g, bool b, bool a)
{
- if (enable && ((G.debug & G_DEBUG_GPU) == 0)) {
- glEnable(GL_LINE_SMOOTH);
- }
- else {
- glDisable(GL_LINE_SMOOTH);
- }
+ GPUStateManager *stack = GPU_context_active_get()->state_manager;
+ auto &state = stack->state;
+ eGPUWriteMask write_mask = state.write_mask;
+ SET_FLAG_FROM_TEST(write_mask, r, GPU_WRITE_RED);
+ SET_FLAG_FROM_TEST(write_mask, g, GPU_WRITE_GREEN);
+ SET_FLAG_FROM_TEST(write_mask, b, GPU_WRITE_BLUE);
+ SET_FLAG_FROM_TEST(write_mask, a, GPU_WRITE_ALPHA);
+ state.write_mask = write_mask;
}
-void GPU_line_width(float width)
+void GPU_depth_mask(bool depth)
{
- float max_size = GPU_max_line_width();
- float final_size = width * PIXELSIZE;
- /* Fix opengl errors on certain platform / drivers. */
- CLAMP(final_size, 1.0f, max_size);
- glLineWidth(final_size);
+ GPUStateManager *stack = GPU_context_active_get()->state_manager;
+ auto &state = stack->state;
+ eGPUWriteMask write_mask = state.write_mask;
+ SET_FLAG_FROM_TEST(write_mask, depth, GPU_WRITE_DEPTH);
+ state.write_mask = write_mask;
}
-void GPU_point_size(float size)
+void GPU_shadow_offset(bool enable)
{
- glPointSize(size * PIXELSIZE);
+ SET_IMMUTABLE_STATE(shadow_bias, enable);
}
-void GPU_polygon_smooth(bool enable)
+void GPU_clip_distances(int distances_enabled)
{
- if (enable && ((G.debug & G_DEBUG_GPU) == 0)) {
- glEnable(GL_POLYGON_SMOOTH);
- }
- else {
- glDisable(GL_POLYGON_SMOOTH);
- }
+ SET_IMMUTABLE_STATE(clip_distances, distances_enabled);
}
-/* Programmable point size
- * - shaders set their own point size when enabled
- * - use glPointSize when disabled */
-void GPU_program_point_size(bool enable)
+void GPU_state_set(eGPUWriteMask write_mask,
+ eGPUBlend blend,
+ eGPUFaceCullTest culling_test,
+ eGPUDepthTest depth_test,
+ eGPUStencilTest stencil_test,
+ eGPUStencilOp stencil_op,
+ eGPUProvokingVertex provoking_vert)
{
- if (enable) {
- glEnable(GL_PROGRAM_POINT_SIZE);
- }
- else {
- glDisable(GL_PROGRAM_POINT_SIZE);
- }
+ GPUStateManager *stack = GPU_context_active_get()->state_manager;
+ auto &state = stack->state;
+ state.write_mask = write_mask;
+ state.blend = blend;
+ state.culling_test = culling_test;
+ state.depth_test = depth_test;
+ state.stencil_test = stencil_test;
+ state.stencil_op = stencil_op;
+ state.provoking_vert = provoking_vert;
}
-void GPU_scissor_test(bool enable)
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Mutable State Setters
+ * \{ */
+
+void GPU_depth_range(float near, float far)
{
- if (enable) {
- glEnable(GL_SCISSOR_TEST);
- }
- else {
- glDisable(GL_SCISSOR_TEST);
- }
+ GPUStateManager *stack = GPU_context_active_get()->state_manager;
+ auto &state = stack->mutable_state;
+ copy_v2_fl2(state.depth_range, near, far);
}
-void GPU_scissor(int x, int y, int width, int height)
+void GPU_line_width(float width)
{
- glScissor(x, y, width, height);
+ SET_MUTABLE_STATE(line_width, width * PIXELSIZE);
}
-void GPU_viewport(int x, int y, int width, int height)
+void GPU_point_size(float size)
{
- glViewport(x, y, width, height);
+ SET_MUTABLE_STATE(point_size, size * PIXELSIZE);
}
-void GPU_scissor_get_f(float coords[4])
+/* Programmable point size
+ * - shaders set their own point size when enabled
+ * - use glPointSize when disabled */
+/* TODO remove and use program point size everywhere */
+void GPU_program_point_size(bool enable)
{
- glGetFloatv(GL_SCISSOR_BOX, coords);
+ GPUStateManager *stack = GPU_context_active_get()->state_manager;
+ auto &state = stack->mutable_state;
+ /* Set point size sign negative to disable. */
+ state.point_size = fabsf(state.point_size) * (enable ? 1 : -1);
}
-void GPU_scissor_get_i(int coords[4])
+void GPU_scissor_test(bool enable)
{
- glGetIntegerv(GL_SCISSOR_BOX, coords);
+ GPUStateManager *stack = GPU_context_active_get()->state_manager;
+ auto &state = stack->mutable_state;
+ /* Set point size sign negative to disable. */
+ state.scissor_rect[2] = abs(state.scissor_rect[2]) * (enable ? 1 : -1);
}
-void GPU_viewport_size_get_f(float coords[4])
+void GPU_scissor(int x, int y, int width, int height)
{
- glGetFloatv(GL_VIEWPORT, coords);
+ GPUStateManager *stack = GPU_context_active_get()->state_manager;
+ auto &state = stack->mutable_state;
+ int scissor_rect[4] = {x, y, width, height};
+ copy_v4_v4_int(state.scissor_rect, scissor_rect);
}
-void GPU_viewport_size_get_i(int coords[4])
+void GPU_viewport(int x, int y, int width, int height)
{
- glGetIntegerv(GL_VIEWPORT, coords);
+ GPUStateManager *stack = GPU_context_active_get()->state_manager;
+ auto &state = stack->mutable_state;
+ int viewport_rect[4] = {x, y, width, height};
+ copy_v4_v4_int(state.viewport_rect, viewport_rect);
}
-void GPU_flush(void)
+void GPU_stencil_reference_set(uint reference)
{
- glFlush();
+ SET_MUTABLE_STATE(stencil_reference, (uint8_t)reference);
}
-
-void GPU_finish(void)
+void GPU_stencil_write_mask_set(uint write_mask)
{
- glFinish();
+ SET_MUTABLE_STATE(stencil_write_mask, (uint8_t)write_mask);
+}
+void GPU_stencil_compare_mask_set(uint compare_mask)
+{
+ SET_MUTABLE_STATE(stencil_compare_mask, (uint8_t)compare_mask);
}
-void GPU_unpack_row_length_set(uint len)
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name State Getters
+ * \{ */
+
+eGPUBlend GPU_blend_get()
{
- glPixelStorei(GL_UNPACK_ROW_LENGTH, len);
+ GPUState &state = GPU_context_active_get()->state_manager->state;
+ return state.blend;
}
-void GPU_logic_op_xor_set(bool enable)
+eGPUWriteMask GPU_write_mask_get()
{
- if (enable) {
- glLogicOp(GL_XOR);
- glEnable(GL_COLOR_LOGIC_OP);
- }
- else {
- glDisable(GL_COLOR_LOGIC_OP);
- }
+ GPUState &state = GPU_context_active_get()->state_manager->state;
+ return state.write_mask;
}
-void GPU_color_mask(bool r, bool g, bool b, bool a)
+bool GPU_depth_test_enabled()
{
- glColorMask(r, g, b, a);
+ GPUState &state = GPU_context_active_get()->state_manager->state;
+ return state.depth_test != GPU_DEPTH_NONE;
}
-void GPU_depth_mask(bool depth)
+void GPU_scissor_get(int coords[4])
{
- glDepthMask(depth);
+ GPUStateMutable &state = GPU_context_active_get()->state_manager->mutable_state;
+ copy_v4_v4_int(coords, state.scissor_rect);
}
-bool GPU_depth_mask_get(void)
+void GPU_viewport_size_get_f(float coords[4])
{
- GLint mask;
- glGetIntegerv(GL_DEPTH_WRITEMASK, &mask);
- return mask == GL_TRUE;
+ GPUStateMutable &state = GPU_context_active_get()->state_manager->mutable_state;
+ for (int i = 0; i < 4; i++) {
+ coords[i] = state.viewport_rect[i];
+ }
}
-void GPU_stencil_mask(uint stencil)
+void GPU_viewport_size_get_i(int coords[4])
{
- glStencilMask(stencil);
+ GPUStateMutable &state = GPU_context_active_get()->state_manager->mutable_state;
+ copy_v4_v4_int(coords, state.viewport_rect);
}
-void GPU_clip_distances(int distances_new)
+bool GPU_depth_mask_get(void)
{
- static int distances_enabled = 0;
- for (int i = 0; i < distances_new; i++) {
- glEnable(GL_CLIP_DISTANCE0 + i);
- }
- for (int i = distances_new; i < distances_enabled; i++) {
- glDisable(GL_CLIP_DISTANCE0 + i);
- }
- distances_enabled = distances_new;
+ GPUState &state = GPU_context_active_get()->state_manager->state;
+ return (state.write_mask & GPU_WRITE_DEPTH) != 0;
}
bool GPU_mipmap_enabled(void)
@@ -274,163 +278,71 @@ bool GPU_mipmap_enabled(void)
return true;
}
-/** \name GPU Push/Pop State
- * \{ */
-
-#define STATE_STACK_DEPTH 16
-
-typedef struct {
- eGPUAttrMask mask;
-
- /* GL_BLEND_BIT */
- uint is_blend : 1;
-
- /* GL_DEPTH_BUFFER_BIT */
- uint is_depth_test : 1;
- int depth_func;
- double depth_clear_value;
- bool depth_write_mask;
-
- /* GL_SCISSOR_BIT */
- int scissor_box[4];
- uint is_scissor_test : 1;
-
- /* GL_VIEWPORT_BIT */
- int viewport[4];
- double near_far[2];
-} GPUAttrValues;
-
-typedef struct {
- GPUAttrValues attr_stack[STATE_STACK_DEPTH];
- uint top;
-} GPUAttrStack;
-
-static GPUAttrStack state = {
- {},
- 0,
-};
+/** \} */
-#define AttrStack state
-#define Attr state.attr_stack[state.top]
+/* -------------------------------------------------------------------- */
+/** \name Context Utils
+ * \{ */
-/**
- * Replacement for glPush/PopAttributes
- *
- * We don't need to cover all the options of legacy OpenGL
- * but simply the ones used by Blender.
- */
-void gpuPushAttr(eGPUAttrMask mask)
+void GPU_flush(void)
{
- Attr.mask = mask;
-
- if ((mask & GPU_DEPTH_BUFFER_BIT) != 0) {
- Attr.is_depth_test = glIsEnabled(GL_DEPTH_TEST);
- glGetIntegerv(GL_DEPTH_FUNC, &Attr.depth_func);
- glGetDoublev(GL_DEPTH_CLEAR_VALUE, &Attr.depth_clear_value);
- glGetBooleanv(GL_DEPTH_WRITEMASK, (GLboolean *)&Attr.depth_write_mask);
- }
-
- if ((mask & GPU_SCISSOR_BIT) != 0) {
- Attr.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
- glGetIntegerv(GL_SCISSOR_BOX, (GLint *)&Attr.scissor_box);
- }
-
- if ((mask & GPU_VIEWPORT_BIT) != 0) {
- glGetDoublev(GL_DEPTH_RANGE, (GLdouble *)&Attr.near_far);
- glGetIntegerv(GL_VIEWPORT, (GLint *)&Attr.viewport);
- }
-
- if ((mask & GPU_BLEND_BIT) != 0) {
- Attr.is_blend = glIsEnabled(GL_BLEND);
- }
-
- BLI_assert(AttrStack.top < STATE_STACK_DEPTH);
- AttrStack.top++;
+ glFlush();
}
-static void restore_mask(GLenum cap, const bool value)
+void GPU_finish(void)
{
- if (value) {
- glEnable(cap);
- }
- else {
- glDisable(cap);
- }
+ glFinish();
}
-void gpuPopAttr(void)
+void GPU_unpack_row_length_set(uint len)
{
- BLI_assert(AttrStack.top > 0);
- AttrStack.top--;
-
- GLint mask = Attr.mask;
-
- if ((mask & GPU_DEPTH_BUFFER_BIT) != 0) {
- restore_mask(GL_DEPTH_TEST, Attr.is_depth_test);
- glDepthFunc(Attr.depth_func);
- glClearDepth(Attr.depth_clear_value);
- glDepthMask(Attr.depth_write_mask);
- }
-
- if ((mask & GPU_VIEWPORT_BIT) != 0) {
- glViewport(Attr.viewport[0], Attr.viewport[1], Attr.viewport[2], Attr.viewport[3]);
- glDepthRange(Attr.near_far[0], Attr.near_far[1]);
- }
-
- if ((mask & GPU_SCISSOR_BIT) != 0) {
- restore_mask(GL_SCISSOR_TEST, Attr.is_scissor_test);
- glScissor(Attr.scissor_box[0], Attr.scissor_box[1], Attr.scissor_box[2], Attr.scissor_box[3]);
- }
-
- if ((mask & GPU_BLEND_BIT) != 0) {
- restore_mask(GL_BLEND, Attr.is_blend);
- }
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, len);
}
-#undef Attr
-#undef AttrStack
+/** \} */
-/* Default OpenGL State
+/* -------------------------------------------------------------------- */
+/** \name Default OpenGL State
*
* This is called on startup, for opengl offscreen render.
* Generally we should always return to this state when
* temporarily modifying the state for drawing, though that are (undocumented)
- * exceptions that we should try to get rid of. */
-
-void GPU_state_init(void)
-{
- GPU_program_point_size(false);
-
- glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
-
- glDisable(GL_BLEND);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_COLOR_LOGIC_OP);
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_DITHER);
-
- glDepthFunc(GL_LEQUAL);
- glDepthRange(0.0, 1.0);
-
- glFrontFace(GL_CCW);
- glCullFace(GL_BACK);
- glDisable(GL_CULL_FACE);
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-
- /* Is default but better be explicit. */
- glEnable(GL_MULTISAMPLE);
-
- /* This is a bit dangerous since addons could change this. */
- glEnable(GL_PRIMITIVE_RESTART);
- glPrimitiveRestartIndex((GLuint)0xFFFFFFFF);
+ * exceptions that we should try to get rid of.
+ * \{ */
- /* TODO: Should become default. But needs at least GL 4.3 */
- if (GLEW_ARB_ES3_compatibility) {
- /* Takes predecence over GL_PRIMITIVE_RESTART */
- glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
- }
+GPUStateManager::GPUStateManager(void)
+{
+ /* Set default state. */
+ state.write_mask = GPU_WRITE_COLOR;
+ state.blend = GPU_BLEND_NONE;
+ state.culling_test = GPU_CULL_NONE;
+ state.depth_test = GPU_DEPTH_NONE;
+ state.stencil_test = GPU_STENCIL_NONE;
+ state.stencil_op = GPU_STENCIL_OP_NONE;
+ state.provoking_vert = GPU_VERTEX_LAST;
+ state.logic_op_xor = false;
+ state.invert_facing = false;
+ state.shadow_bias = false;
+ state.polygon_smooth = false;
+ state.clip_distances = 0;
+
+ /* TODO: We should have better default for viewport and scissors.
+ * For now it's not important since they are overwritten at soon as a framebuffer is bound. */
+ mutable_state.viewport_rect[0] = 0;
+ mutable_state.viewport_rect[1] = 0;
+ mutable_state.viewport_rect[2] = 10;
+ mutable_state.viewport_rect[3] = 10;
+ mutable_state.scissor_rect[0] = 0;
+ mutable_state.scissor_rect[1] = 0;
+ mutable_state.scissor_rect[2] = -10; /* Disable */
+ mutable_state.scissor_rect[3] = 10;
+ mutable_state.depth_range[0] = 0.0f;
+ mutable_state.depth_range[1] = 1.0f;
+ mutable_state.point_size = 1.0f;
+ mutable_state.line_width = 1.0f;
+ mutable_state.stencil_write_mask = 0x00;
+ mutable_state.stencil_compare_mask = 0x00;
+ mutable_state.stencil_reference = 0x00;
}
/** \} */
diff --git a/source/blender/gpu/intern/gpu_state_private.hh b/source/blender/gpu/intern/gpu_state_private.hh
new file mode 100644
index 00000000000..1ba79c7c048
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_state_private.hh
@@ -0,0 +1,167 @@
+/*
+ * 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 2020, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#pragma once
+
+#include "BLI_utildefines.h"
+
+#include "GPU_state.h"
+
+#include <cstring>
+
+namespace blender {
+namespace gpu {
+
+/* Encapsulate all pipeline state that we need to track.
+ * Try to keep small to reduce validation time. */
+union GPUState {
+ struct {
+ eGPUWriteMask write_mask : 13;
+ eGPUBlend blend : 4;
+ eGPUFaceCullTest culling_test : 2;
+ eGPUDepthTest depth_test : 3;
+ eGPUStencilTest stencil_test : 3;
+ eGPUStencilOp stencil_op : 3;
+ eGPUProvokingVertex provoking_vert : 1;
+ /** Enable bits. */
+ uint32_t logic_op_xor : 1;
+ uint32_t invert_facing : 1;
+ uint32_t shadow_bias : 1;
+ /** Number of clip distances enabled. */
+ /* TODO(fclem) This should be a shader property. */
+ uint32_t clip_distances : 3;
+ /* TODO(fclem) remove, old opengl features. */
+ uint32_t polygon_smooth : 1;
+ uint32_t line_smooth : 1;
+ };
+ /* Here to allow fast bitwise ops. */
+ uint64_t data;
+};
+
+BLI_STATIC_ASSERT(sizeof(GPUState) == sizeof(uint64_t), "GPUState is too big.");
+
+inline bool operator==(const GPUState &a, const GPUState &b)
+{
+ return a.data == b.data;
+}
+
+inline bool operator!=(const GPUState &a, const GPUState &b)
+{
+ return !(a == b);
+}
+
+inline GPUState operator^(const GPUState &a, const GPUState &b)
+{
+ GPUState r;
+ r.data = a.data ^ b.data;
+ return r;
+}
+
+inline GPUState operator~(const GPUState &a)
+{
+ GPUState r;
+ r.data = ~a.data;
+ return r;
+}
+
+/* Mutable state that does not require pipeline change. */
+union GPUStateMutable {
+ struct {
+ /* Viewport State */
+ /** TODO put inside GPUFramebuffer. */
+ /** Offset + Extent of the drawable region inside the framebuffer. */
+ int viewport_rect[4];
+ /** Offset + Extent of the scissor region inside the framebuffer. */
+ int scissor_rect[4];
+ /** TODO remove */
+ float depth_range[2];
+ /** TODO remove, use explicit clear calls. */
+ float clear_color[4];
+ float clear_depth;
+ /** Negative if using program point size. */
+ /* TODO(fclem) should be passed as uniform to all shaders. */
+ float point_size;
+ /** Not supported on every platform. Prefer using wideline shader. */
+ float line_width;
+ /** Mutable stencil states. */
+ uint8_t stencil_write_mask;
+ uint8_t stencil_compare_mask;
+ uint8_t stencil_reference;
+ uint8_t _pad0;
+ /* IMPORTANT: ensure x64 stuct alignment. */
+ };
+ /* Here to allow fast bitwise ops. */
+ uint64_t data[9];
+};
+
+BLI_STATIC_ASSERT(sizeof(GPUStateMutable) == sizeof(GPUStateMutable::data),
+ "GPUStateMutable is too big.");
+
+inline bool operator==(const GPUStateMutable &a, const GPUStateMutable &b)
+{
+ return memcmp(&a, &b, sizeof(GPUStateMutable)) == 0;
+}
+
+inline bool operator!=(const GPUStateMutable &a, const GPUStateMutable &b)
+{
+ return !(a == b);
+}
+
+inline GPUStateMutable operator^(const GPUStateMutable &a, const GPUStateMutable &b)
+{
+ GPUStateMutable r;
+ for (int i = 0; i < ARRAY_SIZE(a.data); i++) {
+ r.data[i] = a.data[i] ^ b.data[i];
+ }
+ return r;
+}
+
+inline GPUStateMutable operator~(const GPUStateMutable &a)
+{
+ GPUStateMutable r;
+ for (int i = 0; i < ARRAY_SIZE(a.data); i++) {
+ r.data[i] = ~a.data[i];
+ }
+ return r;
+}
+
+class GPUStateManager {
+ public:
+ GPUState state;
+ GPUStateMutable mutable_state;
+
+ public:
+ GPUStateManager();
+ virtual ~GPUStateManager(){};
+
+ virtual void set_state(const GPUState &state) = 0;
+ virtual void set_mutable_state(const GPUStateMutable &state) = 0;
+
+ inline void apply_state(void)
+ {
+ this->set_state(this->state);
+ this->set_mutable_state(this->mutable_state);
+ };
+};
+
+} // namespace gpu
+} // namespace blender
diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc
index a45bd222664..91990dac83f 100644
--- a/source/blender/gpu/intern/gpu_texture.cc
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -615,7 +615,7 @@ static bool gpu_texture_check_capacity(
GPUTexture *tex, GLenum proxy, GLenum internalformat, GLenum data_format, GLenum data_type)
{
if (proxy == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB &&
- GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_MAC, GPU_DRIVER_ANY)) {
+ GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) {
/* Special fix for T79703. */
/* Depth has already been checked. */
return tex->w <= GPU_max_cube_map_size();
@@ -1611,6 +1611,9 @@ void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat gpu_data_format, const vo
/* This means that this function can only be used in one context for each texture. */
BLI_assert(tex->copy_fb_ctx == GPU_context_active_get());
+ int viewport[4];
+ GPU_viewport_size_get_i(viewport);
+
glBindFramebuffer(GL_FRAMEBUFFER, tex->copy_fb);
glViewport(0, 0, tex->w, tex->h);
@@ -1675,6 +1678,8 @@ void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat gpu_data_format, const vo
glClear(GL_COLOR_BUFFER_BIT);
}
+ glViewport(UNPACK4(viewport));
+
if (prev_fb) {
GPU_framebuffer_bind(prev_fb);
}
diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc
index 2e8017660d0..2b16f4482b4 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.cc
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -24,7 +24,9 @@
*/
#include "GPU_vertex_format.h"
+#include "gpu_shader_private.hh"
#include "gpu_vertex_format_private.h"
+
#include <stddef.h>
#include <string.h>
@@ -32,15 +34,14 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
-#include "GPU_shader.h"
-#include "gpu_shader_private.h"
-
#define PACK_DEBUG 0
#if PACK_DEBUG
# include <stdio.h>
#endif
+using namespace blender::gpu;
+
void GPU_vertformat_clear(GPUVertFormat *format)
{
#if TRUST_NO_ONE
@@ -404,112 +405,8 @@ void VertexFormat_pack(GPUVertFormat *format)
format->packed = true;
}
-static uint calc_component_size(const GLenum gl_type)
+void GPU_vertformat_from_shader(GPUVertFormat *format, const struct GPUShader *gpushader)
{
- switch (gl_type) {
- case GL_FLOAT_VEC2:
- case GL_INT_VEC2:
- case GL_UNSIGNED_INT_VEC2:
- return 2;
- case GL_FLOAT_VEC3:
- case GL_INT_VEC3:
- case GL_UNSIGNED_INT_VEC3:
- return 3;
- case GL_FLOAT_VEC4:
- case GL_FLOAT_MAT2:
- case GL_INT_VEC4:
- case GL_UNSIGNED_INT_VEC4:
- return 4;
- case GL_FLOAT_MAT3:
- return 9;
- case GL_FLOAT_MAT4:
- return 16;
- case GL_FLOAT_MAT2x3:
- case GL_FLOAT_MAT3x2:
- return 6;
- case GL_FLOAT_MAT2x4:
- case GL_FLOAT_MAT4x2:
- return 8;
- case GL_FLOAT_MAT3x4:
- case GL_FLOAT_MAT4x3:
- return 12;
- default:
- return 1;
- }
-}
-
-static void get_fetch_mode_and_comp_type(int gl_type,
- GPUVertCompType *r_comp_type,
- GPUVertFetchMode *r_fetch_mode)
-{
- switch (gl_type) {
- case GL_FLOAT:
- case GL_FLOAT_VEC2:
- case GL_FLOAT_VEC3:
- case GL_FLOAT_VEC4:
- case GL_FLOAT_MAT2:
- case GL_FLOAT_MAT3:
- case GL_FLOAT_MAT4:
- case GL_FLOAT_MAT2x3:
- case GL_FLOAT_MAT2x4:
- case GL_FLOAT_MAT3x2:
- case GL_FLOAT_MAT3x4:
- case GL_FLOAT_MAT4x2:
- case GL_FLOAT_MAT4x3:
- *r_comp_type = GPU_COMP_F32;
- *r_fetch_mode = GPU_FETCH_FLOAT;
- break;
- case GL_INT:
- case GL_INT_VEC2:
- case GL_INT_VEC3:
- case GL_INT_VEC4:
- *r_comp_type = GPU_COMP_I32;
- *r_fetch_mode = GPU_FETCH_INT;
- break;
- case GL_UNSIGNED_INT:
- case GL_UNSIGNED_INT_VEC2:
- case GL_UNSIGNED_INT_VEC3:
- case GL_UNSIGNED_INT_VEC4:
- *r_comp_type = GPU_COMP_U32;
- *r_fetch_mode = GPU_FETCH_INT;
- break;
- default:
- BLI_assert(0);
- }
-}
-
-void GPU_vertformat_from_shader(GPUVertFormat *format, const GPUShader *shader)
-{
- GPU_vertformat_clear(format);
- GPUVertAttr *attr = &format->attrs[0];
-
- GLint attr_len;
- glGetProgramiv(shader->program, GL_ACTIVE_ATTRIBUTES, &attr_len);
-
- for (int i = 0; i < attr_len; i++) {
- char name[256];
- GLenum gl_type;
- GLint size;
- glGetActiveAttrib(shader->program, i, sizeof(name), NULL, &size, &gl_type, name);
-
- /* Ignore OpenGL names like `gl_BaseInstanceARB`, `gl_InstanceID` and `gl_VertexID`. */
- if (glGetAttribLocation(shader->program, name) == -1) {
- continue;
- }
-
- format->name_len++; /* multiname support */
- format->attr_len++;
-
- GPUVertCompType comp_type;
- GPUVertFetchMode fetch_mode;
- get_fetch_mode_and_comp_type(gl_type, &comp_type, &fetch_mode);
-
- attr->names[attr->name_len++] = copy_attr_name(format, name);
- attr->offset = 0; /* offsets & stride are calculated later (during pack) */
- attr->comp_len = calc_component_size(gl_type) * size;
- attr->sz = attr->comp_len * 4;
- attr->fetch_mode = fetch_mode;
- attr->comp_type = comp_type;
- attr += 1;
- }
+ const Shader *shader = static_cast<const Shader *>(gpushader);
+ shader->vertformat_from_shader(format);
}
diff --git a/source/blender/gpu/opengl/gl_backend.hh b/source/blender/gpu/opengl/gl_backend.hh
index eba275f0245..63a14af6612 100644
--- a/source/blender/gpu/opengl/gl_backend.hh
+++ b/source/blender/gpu/opengl/gl_backend.hh
@@ -30,6 +30,7 @@
#include "gl_batch.hh"
#include "gl_context.hh"
#include "gl_drawlist.hh"
+#include "gl_shader.hh"
namespace blender {
namespace gpu {
@@ -54,6 +55,11 @@ class GLBackend : public GPUBackend {
return new GLDrawList(list_length);
};
+ Shader *shader_alloc(const char *name)
+ {
+ return new GLShader(name);
+ };
+
/* TODO remove */
void buf_free(GLuint buf_id);
void tex_free(GLuint tex_id);
diff --git a/source/blender/gpu/opengl/gl_batch.cc b/source/blender/gpu/opengl/gl_batch.cc
index 00e1a61f7cf..fade8763065 100644
--- a/source/blender/gpu/opengl/gl_batch.cc
+++ b/source/blender/gpu/opengl/gl_batch.cc
@@ -33,7 +33,6 @@
#include "gpu_batch_private.hh"
#include "gpu_primitive_private.h"
-#include "gpu_shader_private.h"
#include "gl_batch.hh"
#include "gl_context.hh"
@@ -301,6 +300,8 @@ GLBatch::~GLBatch()
void GLBatch::bind(int i_first)
{
+ GPU_context_active_get()->state_manager->apply_state();
+
if (flag & GPU_BATCH_DIRTY) {
vao_cache_.clear();
}
@@ -325,6 +326,8 @@ void GLBatch::draw(int v_first, int v_count, int i_first, int i_count)
{
this->bind(i_first);
+ BLI_assert(v_count > 0 && i_count > 0);
+
GLenum gl_type = convert_prim_type_to_gl(prim_type);
if (elem) {
diff --git a/source/blender/gpu/opengl/gl_context.cc b/source/blender/gpu/opengl/gl_context.cc
index dd413612879..11f313f639b 100644
--- a/source/blender/gpu/opengl/gl_context.cc
+++ b/source/blender/gpu/opengl/gl_context.cc
@@ -30,6 +30,8 @@
#include "gpu_context_private.hh"
+#include "gl_state.hh"
+
#include "gl_backend.hh" /* TODO remove */
#include "gl_context.hh"
@@ -54,6 +56,8 @@ GLContext::GLContext(void *ghost_window, GLSharedOrphanLists &shared_orphan_list
glBindBuffer(GL_ARRAY_BUFFER, default_attr_vbo_);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ state_manager = new GLStateManager();
}
GLContext::~GLContext()
diff --git a/source/blender/gpu/opengl/gl_drawlist.cc b/source/blender/gpu/opengl/gl_drawlist.cc
index c121fb9ba2c..16ea924d8dc 100644
--- a/source/blender/gpu/opengl/gl_drawlist.cc
+++ b/source/blender/gpu/opengl/gl_drawlist.cc
@@ -151,6 +151,11 @@ void GLDrawList::append(GPUBatch *batch, int i_first, int i_count)
v_count_ = batch->elem ? batch->elem->index_len : batch->verts[0]->vertex_len;
}
+ if (v_count_ == 0) {
+ /* Nothing to draw. */
+ return;
+ }
+
if (MDI_INDEXED) {
GLDrawCommandIndexed *cmd = reinterpret_cast<GLDrawCommandIndexed *>(data_ + command_offset_);
cmd->v_first = v_first_;
@@ -235,6 +240,8 @@ void GLDrawList::submit(void)
}
/* Do not submit this buffer again. */
command_len_ = 0;
+ /* Avoid keeping reference to the batch. */
+ batch_ = NULL;
}
-/** \} */ \ No newline at end of file
+/** \} */
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
new file mode 100644
index 00000000000..ea33ff00d69
--- /dev/null
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -0,0 +1,443 @@
+/*
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "BKE_global.h"
+
+#include "BLI_string.h"
+
+#include "GPU_extensions.h"
+#include "GPU_platform.h"
+
+#include "gl_shader.hh"
+
+using namespace blender;
+using namespace blender::gpu;
+
+/* -------------------------------------------------------------------- */
+/** \name Creation / Destruction
+ * \{ */
+
+GLShader::GLShader(const char *name) : Shader(name)
+{
+#if 0 /* Would be nice to have, but for now the Deferred compilation \
+ * does not have a GPUContext. */
+ BLI_assert(GPU_context_active_get() != NULL);
+#endif
+ shader_program_ = glCreateProgram();
+
+#ifndef __APPLE__
+ if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) {
+ char sh_name[64];
+ BLI_snprintf(sh_name, sizeof(sh_name), "ShaderProgram-%s", name);
+ glObjectLabel(GL_PROGRAM, shader_program_, -1, sh_name);
+ }
+#endif
+}
+
+GLShader::~GLShader(void)
+{
+#if 0 /* Would be nice to have, but for now the Deferred compilation \
+ * does not have a GPUContext. */
+ BLI_assert(GPU_context_active_get() != NULL);
+#endif
+ /* Invalid handles are silently ignored. */
+ glDeleteShader(vert_shader_);
+ glDeleteShader(geom_shader_);
+ glDeleteShader(frag_shader_);
+ glDeleteProgram(shader_program_);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Shader stage creation
+ * \{ */
+
+char *GLShader::glsl_patch_get(void)
+{
+ /** Used for shader patching. Init once. */
+ static char patch[512] = "\0";
+ if (patch[0] != '\0') {
+ return patch;
+ }
+
+ size_t slen = 0;
+ /* Version need to go first. */
+ STR_CONCAT(patch, slen, "#version 330\n");
+
+ /* Enable extensions for features that are not part of our base GLSL version
+ * don't use an extension for something already available! */
+ if (GLEW_ARB_texture_gather) {
+ /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather
+ * is reported to be supported but yield a compile error (see T55802). */
+ if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) || GLEW_VERSION_4_0) {
+ STR_CONCAT(patch, slen, "#extension GL_ARB_texture_gather: enable\n");
+
+ /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the
+ * shader so double check the preprocessor define (see T56544). */
+ if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) {
+ STR_CONCAT(patch, slen, "#ifdef GL_ARB_texture_gather\n");
+ STR_CONCAT(patch, slen, "# define GPU_ARB_texture_gather\n");
+ STR_CONCAT(patch, slen, "#endif\n");
+ }
+ else {
+ STR_CONCAT(patch, slen, "#define GPU_ARB_texture_gather\n");
+ }
+ }
+ }
+ if (GLEW_ARB_shader_draw_parameters) {
+ STR_CONCAT(patch, slen, "#extension GL_ARB_shader_draw_parameters : enable\n");
+ STR_CONCAT(patch, slen, "#define GPU_ARB_shader_draw_parameters\n");
+ }
+ if (GPU_arb_texture_cube_map_array_is_supported()) {
+ STR_CONCAT(patch, slen, "#extension GL_ARB_texture_cube_map_array : enable\n");
+ STR_CONCAT(patch, slen, "#define GPU_ARB_texture_cube_map_array\n");
+ }
+
+ /* Derivative sign can change depending on implementation. */
+ float derivatives[2];
+ GPU_get_dfdy_factors(derivatives);
+ STR_CONCATF(patch, slen, "#define DFDX_SIGN %1.1f\n", derivatives[0]);
+ STR_CONCATF(patch, slen, "#define DFDY_SIGN %1.1f\n", derivatives[1]);
+
+ BLI_assert(slen < sizeof(patch));
+ return patch;
+}
+
+/* Create, compile and attach the shader stage to the shader program. */
+GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan<const char *> sources)
+{
+ GLuint shader = glCreateShader(gl_stage);
+ if (shader == 0) {
+ fprintf(stderr, "GLShader: Error: Could not create shader object.");
+ return 0;
+ }
+
+ /* Patch the shader code using the first source slot. */
+ sources[0] = glsl_patch_get();
+
+ glShaderSource(shader, sources.size(), sources.data(), NULL);
+ glCompileShader(shader);
+
+ GLint status;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+ if (!status || (G.debug & G_DEBUG_GPU)) {
+ char log[5000] = "";
+ glGetShaderInfoLog(shader, sizeof(log), NULL, log);
+ if (log[0] != '\0') {
+ this->print_errors(sources, log);
+ }
+ }
+ if (!status) {
+ glDeleteShader(shader);
+ return 0;
+ }
+
+#ifndef __APPLE__
+ if ((G.debug & G_DEBUG_GPU) && (GLEW_VERSION_4_3 || GLEW_KHR_debug)) {
+ char sh_name[64];
+ switch (gl_stage) {
+ case GL_VERTEX_SHADER:
+ BLI_snprintf(sh_name, sizeof(sh_name), "VertShader-%s", name);
+ break;
+ case GL_GEOMETRY_SHADER:
+ BLI_snprintf(sh_name, sizeof(sh_name), "GeomShader-%s", name);
+ break;
+ case GL_FRAGMENT_SHADER:
+ BLI_snprintf(sh_name, sizeof(sh_name), "FragShader-%s", name);
+ break;
+ }
+ glObjectLabel(GL_SHADER, shader, -1, sh_name);
+ }
+#endif
+
+ glAttachShader(shader_program_, shader);
+ return shader;
+}
+
+void GLShader::vertex_shader_from_glsl(MutableSpan<const char *> sources)
+{
+ vert_shader_ = this->create_shader_stage(GL_VERTEX_SHADER, sources);
+}
+
+void GLShader::geometry_shader_from_glsl(MutableSpan<const char *> sources)
+{
+ geom_shader_ = this->create_shader_stage(GL_GEOMETRY_SHADER, sources);
+}
+
+void GLShader::fragment_shader_from_glsl(MutableSpan<const char *> sources)
+{
+ frag_shader_ = this->create_shader_stage(GL_FRAGMENT_SHADER, sources);
+}
+
+bool GLShader::finalize(void)
+{
+ glLinkProgram(shader_program_);
+
+ GLint status;
+ glGetProgramiv(shader_program_, GL_LINK_STATUS, &status);
+ if (!status) {
+ char log[5000];
+ glGetProgramInfoLog(shader_program_, sizeof(log), NULL, log);
+ fprintf(stderr, "\nLinking Error:\n\n%s", log);
+ return false;
+ }
+
+ /* TODO(fclem) We need this to modify the image binding points using glUniform.
+ * This could be avoided using glProgramUniform in GL 4.1. */
+ glUseProgram(shader_program_);
+ interface = GPU_shaderinterface_create(shader_program_);
+
+ return true;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Binding
+ * \{ */
+
+void GLShader::bind(void)
+{
+ BLI_assert(shader_program_ != 0);
+ glUseProgram(shader_program_);
+}
+
+void GLShader::unbind(void)
+{
+#ifndef NDEBUG
+ glUseProgram(0);
+#endif
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform feedback
+ *
+ * TODO(fclem) Should be replaced by compute shaders.
+ * \{ */
+
+/* Should be called before linking. */
+void GLShader::transform_feedback_names_set(Span<const char *> name_list,
+ const eGPUShaderTFBType geom_type)
+{
+ glTransformFeedbackVaryings(
+ shader_program_, name_list.size(), name_list.data(), GL_INTERLEAVED_ATTRIBS);
+ transform_feedback_type_ = geom_type;
+}
+
+bool GLShader::transform_feedback_enable(GPUVertBuf *buf)
+{
+ if (transform_feedback_type_ == GPU_SHADER_TFB_NONE) {
+ return false;
+ }
+
+ BLI_assert(buf->vbo_id != 0);
+
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf->vbo_id);
+
+ switch (transform_feedback_type_) {
+ case GPU_SHADER_TFB_POINTS:
+ glBeginTransformFeedback(GL_POINTS);
+ break;
+ case GPU_SHADER_TFB_LINES:
+ glBeginTransformFeedback(GL_LINES);
+ break;
+ case GPU_SHADER_TFB_TRIANGLES:
+ glBeginTransformFeedback(GL_TRIANGLES);
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+void GLShader::transform_feedback_disable(void)
+{
+ glEndTransformFeedback();
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Uniforms setters
+ * \{ */
+
+void GLShader::uniform_float(int location, int comp_len, int array_size, const float *data)
+{
+ switch (comp_len) {
+ case 1:
+ glUniform1fv(location, array_size, data);
+ break;
+ case 2:
+ glUniform2fv(location, array_size, data);
+ break;
+ case 3:
+ glUniform3fv(location, array_size, data);
+ break;
+ case 4:
+ glUniform4fv(location, array_size, data);
+ break;
+ case 9:
+ glUniformMatrix3fv(location, array_size, 0, data);
+ break;
+ case 16:
+ glUniformMatrix4fv(location, array_size, 0, data);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+}
+
+void GLShader::uniform_int(int location, int comp_len, int array_size, const int *data)
+{
+ switch (comp_len) {
+ case 1:
+ glUniform1iv(location, array_size, data);
+ break;
+ case 2:
+ glUniform2iv(location, array_size, data);
+ break;
+ case 3:
+ glUniform3iv(location, array_size, data);
+ break;
+ case 4:
+ glUniform4iv(location, array_size, data);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name GPUVertFormat from Shader
+ * \{ */
+
+static uint calc_component_size(const GLenum gl_type)
+{
+ switch (gl_type) {
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ return 2;
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ return 3;
+ case GL_FLOAT_VEC4:
+ case GL_FLOAT_MAT2:
+ case GL_INT_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ return 4;
+ case GL_FLOAT_MAT3:
+ return 9;
+ case GL_FLOAT_MAT4:
+ return 16;
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT3x2:
+ return 6;
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT4x2:
+ return 8;
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x3:
+ return 12;
+ default:
+ return 1;
+ }
+}
+
+static void get_fetch_mode_and_comp_type(int gl_type,
+ GPUVertCompType *r_comp_type,
+ GPUVertFetchMode *r_fetch_mode)
+{
+ switch (gl_type) {
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT4x3:
+ *r_comp_type = GPU_COMP_F32;
+ *r_fetch_mode = GPU_FETCH_FLOAT;
+ break;
+ case GL_INT:
+ case GL_INT_VEC2:
+ case GL_INT_VEC3:
+ case GL_INT_VEC4:
+ *r_comp_type = GPU_COMP_I32;
+ *r_fetch_mode = GPU_FETCH_INT;
+ break;
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC4:
+ *r_comp_type = GPU_COMP_U32;
+ *r_fetch_mode = GPU_FETCH_INT;
+ break;
+ default:
+ BLI_assert(0);
+ }
+}
+
+void GLShader::vertformat_from_shader(GPUVertFormat *format) const
+{
+ GPU_vertformat_clear(format);
+
+ GLint attr_len;
+ glGetProgramiv(shader_program_, GL_ACTIVE_ATTRIBUTES, &attr_len);
+
+ for (int i = 0; i < attr_len; i++) {
+ char name[256];
+ GLenum gl_type;
+ GLint size;
+ glGetActiveAttrib(shader_program_, i, sizeof(name), NULL, &size, &gl_type, name);
+
+ /* Ignore OpenGL names like `gl_BaseInstanceARB`, `gl_InstanceID` and `gl_VertexID`. */
+ if (glGetAttribLocation(shader_program_, name) == -1) {
+ continue;
+ }
+
+ GPUVertCompType comp_type;
+ GPUVertFetchMode fetch_mode;
+ get_fetch_mode_and_comp_type(gl_type, &comp_type, &fetch_mode);
+
+ int comp_len = calc_component_size(gl_type) * size;
+
+ GPU_vertformat_attr_add(format, name, comp_type, comp_len, fetch_mode);
+ }
+}
+
+/** \} */
diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh
new file mode 100644
index 00000000000..b432a04abaa
--- /dev/null
+++ b/source/blender/gpu/opengl/gl_shader.hh
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup gpu
+ *
+ * GPUDrawList is an API to do lots of similar draw-calls very fast using
+ * multi-draw-indirect. There is a fallback if the feature is not supported.
+ */
+
+#pragma once
+
+#include "MEM_guardedalloc.h"
+
+#include "glew-mx.h"
+
+#include "gpu_shader_private.hh"
+
+namespace blender {
+namespace gpu {
+
+class GLShader : public Shader {
+ private:
+ /** Handle for full program (links shader stages below). */
+ GLuint shader_program_ = 0;
+
+ GLuint vert_shader_ = 0;
+ GLuint geom_shader_ = 0;
+ GLuint frag_shader_ = 0;
+
+ eGPUShaderTFBType transform_feedback_type_ = GPU_SHADER_TFB_NONE;
+
+ public:
+ GLShader(const char *name);
+ ~GLShader();
+
+ /* Return true on success. */
+ void vertex_shader_from_glsl(MutableSpan<const char *> sources) override;
+ void geometry_shader_from_glsl(MutableSpan<const char *> sources) override;
+ void fragment_shader_from_glsl(MutableSpan<const char *> sources) override;
+ bool finalize(void) override;
+
+ void transform_feedback_names_set(Span<const char *> name_list,
+ const eGPUShaderTFBType geom_type) override;
+ bool transform_feedback_enable(GPUVertBuf *buf) override;
+ void transform_feedback_disable(void) override;
+
+ void bind(void) override;
+ void unbind(void) override;
+
+ void uniform_float(int location, int comp_len, int array_size, const float *data) override;
+ void uniform_int(int location, int comp_len, int array_size, const int *data) override;
+
+ void vertformat_from_shader(GPUVertFormat *format) const override;
+
+ private:
+ char *glsl_patch_get(void);
+
+ GLuint create_shader_stage(GLenum gl_stage, MutableSpan<const char *> sources);
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("GLShader");
+};
+
+} // namespace gpu
+} // namespace blender
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc
new file mode 100644
index 00000000000..3e3695e0b48
--- /dev/null
+++ b/source/blender/gpu/opengl/gl_state.cc
@@ -0,0 +1,423 @@
+/*
+ * 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 2020, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "BLI_math_base.h"
+
+#include "GPU_extensions.h"
+
+#include "glew-mx.h"
+
+#include "gl_state.hh"
+
+using namespace blender::gpu;
+
+/* -------------------------------------------------------------------- */
+/** \name GLStateManager
+ * \{ */
+
+GLStateManager::GLStateManager(void) : GPUStateManager()
+{
+ /* Set other states that never change. */
+ glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+ glEnable(GL_MULTISAMPLE);
+ glEnable(GL_PRIMITIVE_RESTART);
+
+ glDisable(GL_DITHER);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+ glPrimitiveRestartIndex((GLuint)0xFFFFFFFF);
+ /* TODO: Should become default. But needs at least GL 4.3 */
+ if (GLEW_ARB_ES3_compatibility) {
+ /* Takes predecence over GL_PRIMITIVE_RESTART */
+ glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
+ }
+
+ /* Force update using default state. */
+ current_ = ~state;
+ current_mutable_ = ~mutable_state;
+ set_state(state);
+ set_mutable_state(mutable_state);
+}
+
+void GLStateManager::set_state(const GPUState &state)
+{
+ GPUState changed = state ^ current_;
+
+ if (changed.blend != 0) {
+ set_blend(state.blend);
+ }
+ if (changed.write_mask != 0) {
+ set_write_mask(state.write_mask);
+ }
+ if (changed.depth_test != 0) {
+ set_depth_test(state.depth_test);
+ }
+ if (changed.stencil_test != 0 || changed.stencil_op != 0) {
+ set_stencil_test(state.stencil_test, state.stencil_op);
+ set_stencil_mask(state.stencil_test, mutable_state);
+ }
+ if (changed.clip_distances != 0) {
+ set_clip_distances(state.clip_distances, current_.clip_distances);
+ }
+ if (changed.culling_test != 0) {
+ set_backface_culling(state.culling_test);
+ }
+ if (changed.logic_op_xor != 0) {
+ set_logic_op(state.logic_op_xor);
+ }
+ if (changed.invert_facing != 0) {
+ set_facing(state.invert_facing);
+ }
+ if (changed.provoking_vert != 0) {
+ set_provoking_vert(state.provoking_vert);
+ }
+ if (changed.shadow_bias != 0) {
+ set_shadow_bias(state.shadow_bias);
+ }
+
+ /* TODO remove */
+ if (changed.polygon_smooth) {
+ if (state.polygon_smooth) {
+ glEnable(GL_POLYGON_SMOOTH);
+ }
+ else {
+ glDisable(GL_POLYGON_SMOOTH);
+ }
+ }
+ if (changed.line_smooth) {
+ if (state.line_smooth) {
+ glEnable(GL_LINE_SMOOTH);
+ }
+ else {
+ glDisable(GL_LINE_SMOOTH);
+ }
+ }
+
+ current_ = state;
+}
+
+void GLStateManager::set_mutable_state(const GPUStateMutable &state)
+{
+ GPUStateMutable changed = state ^ current_mutable_;
+
+ if ((changed.viewport_rect[0] != 0) || (changed.viewport_rect[1] != 0) ||
+ (changed.viewport_rect[2] != 0) || (changed.viewport_rect[3] != 0)) {
+ glViewport(UNPACK4(state.viewport_rect));
+ }
+
+ if ((changed.scissor_rect[0] != 0) || (changed.scissor_rect[1] != 0) ||
+ (changed.scissor_rect[2] != 0) || (changed.scissor_rect[3] != 0)) {
+ if ((state.scissor_rect[2] > 0)) {
+ glScissor(UNPACK4(state.scissor_rect));
+ glEnable(GL_SCISSOR_TEST);
+ }
+ else {
+ glDisable(GL_SCISSOR_TEST);
+ }
+ }
+
+ /* TODO remove, should be uniform. */
+ if (changed.point_size != 0) {
+ if (state.point_size > 0.0f) {
+ glEnable(GL_PROGRAM_POINT_SIZE);
+ glPointSize(state.point_size);
+ }
+ else {
+ glDisable(GL_PROGRAM_POINT_SIZE);
+ }
+ }
+
+ if (changed.line_width != 0) {
+ /* TODO remove, should use wide line shader. */
+ glLineWidth(clamp_f(state.line_width, 1.0f, GPU_max_line_width()));
+ }
+
+ if (changed.depth_range[0] != 0 || changed.depth_range[1] != 0) {
+ /* TODO remove, should modify the projection matrix instead. */
+ glDepthRange(UNPACK2(state.depth_range));
+ }
+
+ if (changed.stencil_compare_mask != 0 || changed.stencil_reference != 0 ||
+ changed.stencil_write_mask != 0) {
+ set_stencil_mask(current_.stencil_test, state);
+ }
+
+ current_mutable_ = state;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name State set functions
+ * \{ */
+
+void GLStateManager::set_write_mask(const eGPUWriteMask value)
+{
+ glDepthMask((value & GPU_WRITE_DEPTH) != 0);
+ glColorMask((value & GPU_WRITE_RED) != 0,
+ (value & GPU_WRITE_GREEN) != 0,
+ (value & GPU_WRITE_BLUE) != 0,
+ (value & GPU_WRITE_ALPHA) != 0);
+
+ if (value == GPU_WRITE_NONE) {
+ glEnable(GL_RASTERIZER_DISCARD);
+ }
+ else {
+ glDisable(GL_RASTERIZER_DISCARD);
+ }
+}
+
+void GLStateManager::set_depth_test(const eGPUDepthTest value)
+{
+ GLenum func;
+ switch (value) {
+ case GPU_DEPTH_LESS:
+ func = GL_LESS;
+ break;
+ case GPU_DEPTH_LESS_EQUAL:
+ func = GL_LEQUAL;
+ break;
+ case GPU_DEPTH_EQUAL:
+ func = GL_EQUAL;
+ break;
+ case GPU_DEPTH_GREATER:
+ func = GL_GREATER;
+ break;
+ case GPU_DEPTH_GREATER_EQUAL:
+ func = GL_GEQUAL;
+ break;
+ case GPU_DEPTH_ALWAYS:
+ default:
+ func = GL_ALWAYS;
+ break;
+ }
+
+ if (value != GPU_DEPTH_NONE) {
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(func);
+ }
+ else {
+ glDisable(GL_DEPTH_TEST);
+ }
+}
+
+void GLStateManager::set_stencil_test(const eGPUStencilTest test, const eGPUStencilOp operation)
+{
+ switch (operation) {
+ case GPU_STENCIL_OP_REPLACE:
+ glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ break;
+ case GPU_STENCIL_OP_COUNT_DEPTH_PASS:
+ glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
+ glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
+ break;
+ case GPU_STENCIL_OP_COUNT_DEPTH_FAIL:
+ glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP);
+ glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP);
+ break;
+ case GPU_STENCIL_OP_NONE:
+ default:
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ }
+
+ if (test != GPU_STENCIL_NONE) {
+ glEnable(GL_STENCIL_TEST);
+ }
+ else {
+ glDisable(GL_STENCIL_TEST);
+ }
+}
+
+void GLStateManager::set_stencil_mask(const eGPUStencilTest test, const GPUStateMutable state)
+{
+ GLenum func;
+ switch (test) {
+ case GPU_STENCIL_NEQUAL:
+ func = GL_NOTEQUAL;
+ break;
+ case GPU_STENCIL_EQUAL:
+ func = GL_EQUAL;
+ break;
+ case GPU_STENCIL_ALWAYS:
+ func = GL_ALWAYS;
+ break;
+ case GPU_STENCIL_NONE:
+ default:
+ glStencilMask(0x00);
+ glStencilFunc(GL_ALWAYS, 0x00, 0x00);
+ return;
+ }
+
+ glStencilMask(state.stencil_write_mask);
+ glStencilFunc(func, state.stencil_reference, state.stencil_compare_mask);
+}
+
+void GLStateManager::set_clip_distances(const int new_dist_len, const int old_dist_len)
+{
+ for (int i = 0; i < new_dist_len; i++) {
+ glEnable(GL_CLIP_DISTANCE0 + i);
+ }
+ for (int i = new_dist_len; i < old_dist_len; i++) {
+ glDisable(GL_CLIP_DISTANCE0 + i);
+ }
+}
+
+void GLStateManager::set_logic_op(const bool enable)
+{
+ if (enable) {
+ glEnable(GL_COLOR_LOGIC_OP);
+ glLogicOp(GL_XOR);
+ }
+ else {
+ glDisable(GL_COLOR_LOGIC_OP);
+ }
+}
+
+void GLStateManager::set_facing(const bool invert)
+{
+ glFrontFace((invert) ? GL_CW : GL_CCW);
+}
+
+void GLStateManager::set_backface_culling(const eGPUFaceCullTest test)
+{
+ if (test != GPU_CULL_NONE) {
+ glEnable(GL_CULL_FACE);
+ glCullFace((test == GPU_CULL_FRONT) ? GL_FRONT : GL_BACK);
+ }
+ else {
+ glDisable(GL_CULL_FACE);
+ }
+}
+
+void GLStateManager::set_provoking_vert(const eGPUProvokingVertex vert)
+{
+ GLenum value = (vert == GPU_VERTEX_FIRST) ? GL_FIRST_VERTEX_CONVENTION :
+ GL_LAST_VERTEX_CONVENTION;
+ glProvokingVertex(value);
+}
+
+void GLStateManager::set_shadow_bias(const bool enable)
+{
+ if (enable) {
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ glEnable(GL_POLYGON_OFFSET_LINE);
+ /* 2.0 Seems to be the lowest possible slope bias that works in every case. */
+ glPolygonOffset(2.0f, 1.0f);
+ }
+ else {
+ glDisable(GL_POLYGON_OFFSET_FILL);
+ glDisable(GL_POLYGON_OFFSET_LINE);
+ }
+}
+
+void GLStateManager::set_blend(const eGPUBlend value)
+{
+ /**
+ * Factors to the equation.
+ * SRC is fragment shader output.
+ * DST is framebuffer color.
+ * final.rgb = SRC.rgb * src_rgb + DST.rgb * dst_rgb;
+ * final.a = SRC.a * src_alpha + DST.a * dst_alpha;
+ **/
+ GLenum src_rgb, src_alpha, dst_rgb, dst_alpha;
+ switch (value) {
+ default:
+ case GPU_BLEND_ALPHA: {
+ src_rgb = GL_SRC_ALPHA;
+ dst_rgb = GL_ONE_MINUS_SRC_ALPHA;
+ src_alpha = GL_ONE;
+ dst_alpha = GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ }
+ case GPU_BLEND_ALPHA_PREMULT: {
+ src_rgb = GL_ONE;
+ dst_rgb = GL_ONE_MINUS_SRC_ALPHA;
+ src_alpha = GL_ONE;
+ dst_alpha = GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ }
+ case GPU_BLEND_ADDITIVE: {
+ /* Do not let alpha accumulate but premult the source RGB by it. */
+ src_rgb = GL_SRC_ALPHA;
+ dst_rgb = GL_ONE;
+ src_alpha = GL_ZERO;
+ dst_alpha = GL_ONE;
+ break;
+ }
+ case GPU_BLEND_SUBTRACT:
+ case GPU_BLEND_ADDITIVE_PREMULT: {
+ /* Let alpha accumulate. */
+ src_rgb = GL_ONE;
+ dst_rgb = GL_ONE;
+ src_alpha = GL_ONE;
+ dst_alpha = GL_ONE;
+ break;
+ }
+ case GPU_BLEND_MULTIPLY: {
+ src_rgb = GL_DST_COLOR;
+ dst_rgb = GL_ZERO;
+ src_alpha = GL_DST_ALPHA;
+ dst_alpha = GL_ZERO;
+ break;
+ }
+ case GPU_BLEND_INVERT: {
+ src_rgb = GL_ONE_MINUS_DST_COLOR;
+ dst_rgb = GL_ZERO;
+ src_alpha = GL_ZERO;
+ dst_alpha = GL_ONE;
+ break;
+ }
+ case GPU_BLEND_OIT: {
+ src_rgb = GL_ONE;
+ dst_rgb = GL_ONE;
+ src_alpha = GL_ZERO;
+ dst_alpha = GL_ONE_MINUS_SRC_ALPHA;
+ break;
+ }
+ case GPU_BLEND_BACKGROUND: {
+ src_rgb = GL_ONE_MINUS_DST_ALPHA;
+ dst_rgb = GL_SRC_ALPHA;
+ src_alpha = GL_ZERO;
+ dst_alpha = GL_SRC_ALPHA;
+ break;
+ }
+ case GPU_BLEND_CUSTOM: {
+ src_rgb = GL_ONE;
+ dst_rgb = GL_SRC1_COLOR;
+ src_alpha = GL_ONE;
+ dst_alpha = GL_SRC1_ALPHA;
+ break;
+ }
+ }
+
+ if (value != GPU_BLEND_NONE) {
+ glBlendFuncSeparate(src_rgb, dst_rgb, src_alpha, dst_alpha);
+ glEnable(GL_BLEND);
+ }
+ else {
+ glDisable(GL_BLEND);
+ }
+}
+
+/** \} */
diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh
new file mode 100644
index 00000000000..b05fcc5d044
--- /dev/null
+++ b/source/blender/gpu/opengl/gl_state.hh
@@ -0,0 +1,63 @@
+/*
+ * 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 2020, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+
+#include "gpu_state_private.hh"
+
+#include "glew-mx.h"
+
+namespace blender {
+namespace gpu {
+
+class GLStateManager : public GPUStateManager {
+ private:
+ /** Current state of the GL implementation. Avoids resetting the whole state for every change. */
+ GPUState current_;
+ GPUStateMutable current_mutable_;
+
+ public:
+ GLStateManager();
+
+ void set_state(const GPUState &state) override;
+ void set_mutable_state(const GPUStateMutable &state) override;
+
+ private:
+ static void set_write_mask(const eGPUWriteMask value);
+ static void set_depth_test(const eGPUDepthTest value);
+ static void set_stencil_test(const eGPUStencilTest test, const eGPUStencilOp operation);
+ static void set_stencil_mask(const eGPUStencilTest test, const GPUStateMutable state);
+ static void set_clip_distances(const int new_dist_len, const int old_dist_len);
+ static void set_logic_op(const bool enable);
+ static void set_facing(const bool invert);
+ static void set_backface_culling(const eGPUFaceCullTest test);
+ static void set_provoking_vert(const eGPUProvokingVertex vert);
+ static void set_shadow_bias(const bool enable);
+ static void set_blend(const eGPUBlend value);
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("GLStateManager")
+};
+
+} // namespace gpu
+} // namespace blender
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl
index 27ca96501ae..5eb853a4c1a 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_output_world.glsl
@@ -6,7 +6,8 @@ void node_output_world(Closure surface, Closure volume, out Closure result)
float alpha = renderPassEnvironment ? 1.0 : backgroundAlpha;
result = CLOSURE_DEFAULT;
result.radiance = surface.radiance * alpha;
- result.transmittance = vec3(1.0 - alpha);
+ result.transmittance = vec3(0.0);
+ result.holdout = (1.0 - alpha);
#else
result = volume;
#endif /* VOLUMETRICS */
diff --git a/source/blender/io/alembic/exporter/abc_export_capi.cc b/source/blender/io/alembic/exporter/abc_export_capi.cc
index 8c5f3d89870..6412379c126 100644
--- a/source/blender/io/alembic/exporter/abc_export_capi.cc
+++ b/source/blender/io/alembic/exporter/abc_export_capi.cc
@@ -67,11 +67,14 @@ namespace io {
namespace alembic {
// Construct the depsgraph for exporting.
-static void build_depsgraph(Depsgraph *depsgraph, Main *bmain)
+static void build_depsgraph(Depsgraph *depsgraph, const bool visible_objects_only)
{
- Scene *scene = DEG_get_input_scene(depsgraph);
- ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
- DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer);
+ if (visible_objects_only) {
+ DEG_graph_build_from_view_layer(depsgraph);
+ }
+ else {
+ DEG_graph_build_for_all_objects(depsgraph);
+ }
}
static void export_startjob(void *customdata,
@@ -91,7 +94,7 @@ static void export_startjob(void *customdata,
*progress = 0.0f;
*do_update = true;
- build_depsgraph(data->depsgraph, data->bmain);
+ build_depsgraph(data->depsgraph, data->params.visible_objects_only);
SubdivModifierDisabler subdiv_disabler(data->depsgraph);
if (!data->params.apply_subdiv) {
subdiv_disabler.disable_modifiers();
@@ -150,7 +153,7 @@ static void export_startjob(void *customdata,
// Update the scene for the next frame to render.
scene->r.cfra = static_cast<int>(frame);
scene->r.subframe = frame - scene->r.cfra;
- BKE_scene_graph_update_for_newframe(data->depsgraph, data->bmain);
+ BKE_scene_graph_update_for_newframe(data->depsgraph);
CLOG_INFO(&LOG, 2, "Exporting frame %.2f", frame);
ExportSubset export_subset = abc_archive->export_subset_for_frame(frame);
@@ -171,7 +174,7 @@ static void export_startjob(void *customdata,
// Finish up by going back to the keyframe that was current before we started.
if (CFRA != orig_frame) {
CFRA = orig_frame;
- BKE_scene_graph_update_for_newframe(data->depsgraph, data->bmain);
+ BKE_scene_graph_update_for_newframe(data->depsgraph);
}
data->export_ok = !data->was_canceled;
diff --git a/source/blender/io/alembic/exporter/abc_writer_abstract.cc b/source/blender/io/alembic/exporter/abc_writer_abstract.cc
index e43b394e27f..84527a12e85 100644
--- a/source/blender/io/alembic/exporter/abc_writer_abstract.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_abstract.cc
@@ -25,6 +25,10 @@
#include "DNA_modifier_types.h"
+#include "DEG_depsgraph.h"
+
+#include <Alembic/AbcGeom/Visibility.h>
+
#include "CLG_log.h"
static CLG_LogRef LOG = {"io.alembic"};
@@ -96,6 +100,18 @@ void ABCAbstractWriter::update_bounding_box(Object *object)
bounding_box_.max.z = -bb->vec[0][1];
}
+void ABCAbstractWriter::write_visibility(const HierarchyContext &context)
+{
+ const bool is_visible = context.is_object_visible(DAG_EVAL_RENDER);
+ Alembic::Abc::OObject abc_object = get_alembic_object();
+
+ if (!abc_visibility_.valid()) {
+ abc_visibility_ = Alembic::AbcGeom::CreateVisibilityProperty(abc_object, timesample_index_);
+ }
+ abc_visibility_.set(is_visible ? Alembic::AbcGeom::kVisibilityVisible :
+ Alembic::AbcGeom::kVisibilityHidden);
+}
+
} // namespace alembic
} // namespace io
} // namespace blender
diff --git a/source/blender/io/alembic/exporter/abc_writer_abstract.h b/source/blender/io/alembic/exporter/abc_writer_abstract.h
index a83373a567a..f46409b7902 100644
--- a/source/blender/io/alembic/exporter/abc_writer_abstract.h
+++ b/source/blender/io/alembic/exporter/abc_writer_abstract.h
@@ -43,6 +43,9 @@ class ABCAbstractWriter : public AbstractHierarchyWriter {
uint32_t timesample_index_;
Imath::Box3d bounding_box_;
+ /* Visibility of this writer's data in Alembic. */
+ Alembic::Abc::OCharProperty abc_visibility_;
+
public:
explicit ABCAbstractWriter(const ABCWriterConstructorArgs &args);
virtual ~ABCAbstractWriter();
@@ -70,6 +73,8 @@ class ABCAbstractWriter : public AbstractHierarchyWriter {
virtual void do_write(HierarchyContext &context) = 0;
virtual void update_bounding_box(Object *object);
+
+ void write_visibility(const HierarchyContext &context);
};
} // namespace alembic
diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
index 89cb76db9a6..517f0212712 100644
--- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
@@ -159,27 +159,10 @@ ModifierData *ABCGenericMeshWriter::get_liquid_sim_modifier(Scene *scene, Object
bool ABCGenericMeshWriter::is_supported(const HierarchyContext *context) const
{
- Object *object = context->object;
- bool is_dupli = context->duplicator != nullptr;
- int base_flag;
-
- if (is_dupli) {
- /* Construct the object's base flags from its dupli-parent, just like is done in
- * deg_objects_dupli_iterator_next(). Without this, the visibility check below will fail. Doing
- * this here, instead of a more suitable location in AbstractHierarchyIterator, prevents
- * copying the Object for every dupli. */
- base_flag = object->base_flag;
- object->base_flag = context->duplicator->base_flag | BASE_FROM_DUPLI;
+ if (args_.export_params->visible_objects_only) {
+ return context->is_object_visible(DAG_EVAL_RENDER);
}
-
- int visibility = BKE_object_visibility(
- object, DAG_EVAL_RENDER /* TODO(Sybren): add evaluation mode to export options? */);
-
- if (is_dupli) {
- object->base_flag = base_flag;
- }
-
- return (visibility & OB_VISIBLE_SELF) != 0;
+ return true;
}
void ABCGenericMeshWriter::do_write(HierarchyContext &context)
diff --git a/source/blender/io/alembic/exporter/abc_writer_transform.cc b/source/blender/io/alembic/exporter/abc_writer_transform.cc
index 39af99c142c..7694066a13d 100644
--- a/source/blender/io/alembic/exporter/abc_writer_transform.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_transform.cc
@@ -92,6 +92,8 @@ void ABCTransformWriter::do_write(HierarchyContext &context)
xform_sample.setMatrix(convert_matrix_datatype(parent_relative_matrix));
xform_sample.setInheritsXforms(true);
abc_xform_schema_.set(xform_sample);
+
+ write_visibility(context);
}
const OObject ABCTransformWriter::get_alembic_object() const
diff --git a/source/blender/io/common/IO_abstract_hierarchy_iterator.h b/source/blender/io/common/IO_abstract_hierarchy_iterator.h
index d0d9d72b880..1d78cc38746 100644
--- a/source/blender/io/common/IO_abstract_hierarchy_iterator.h
+++ b/source/blender/io/common/IO_abstract_hierarchy_iterator.h
@@ -37,6 +37,8 @@
#include "IO_dupli_persistent_id.hh"
+#include "DEG_depsgraph.h"
+
#include <map>
#include <set>
#include <string>
@@ -111,6 +113,8 @@ struct HierarchyContext {
bool is_instance() const;
void mark_as_instance_of(const std::string &reference_export_path);
void mark_as_not_instanced();
+
+ bool is_object_visible(const enum eEvaluationMode evaluation_mode) const;
};
/* Abstract writer for objects. Create concrete subclasses to write to USD, Alembic, etc.
diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
index fbefc8c8e7e..d825625cafc 100644
--- a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc
@@ -28,6 +28,7 @@
#include "BKE_anim_data.h"
#include "BKE_duplilist.h"
#include "BKE_key.h"
+#include "BKE_object.h"
#include "BKE_particle.h"
#include "BLI_assert.h"
@@ -77,6 +78,29 @@ void HierarchyContext::mark_as_not_instanced()
original_export_path.clear();
}
+bool HierarchyContext::is_object_visible(const enum eEvaluationMode evaluation_mode) const
+{
+ const bool is_dupli = duplicator != nullptr;
+ int base_flag;
+
+ if (is_dupli) {
+ /* Construct the object's base flags from its dupli-parent, just like is done in
+ * deg_objects_dupli_iterator_next(). Without this, the visibility check below will fail. Doing
+ * this here, instead of a more suitable location in AbstractHierarchyIterator, prevents
+ * copying the Object for every dupli. */
+ base_flag = object->base_flag;
+ object->base_flag = duplicator->base_flag | BASE_FROM_DUPLI;
+ }
+
+ const int visibility = BKE_object_visibility(object, evaluation_mode);
+
+ if (is_dupli) {
+ object->base_flag = base_flag;
+ }
+
+ return (visibility & OB_VISIBLE_SELF) != 0;
+}
+
EnsuredWriter::EnsuredWriter() : writer_(nullptr), newly_created_(false)
{
}
diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc
index cbb2e63a99f..27196994a3c 100644
--- a/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc
+++ b/source/blender/io/common/intern/abstract_hierarchy_iterator_test.cc
@@ -20,8 +20,11 @@
#include "tests/blendfile_loading_base_test.h"
+#include "BKE_scene.h"
#include "BLI_math.h"
+#include "BLO_readfile.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
#include "DNA_object_types.h"
#include <map>
@@ -99,7 +102,7 @@ class TestingHierarchyIterator : public AbstractHierarchyIterator {
}
};
-class USDHierarchyIteratorTest : public BlendfileLoadingBaseTest {
+class AbstractHierarchyIteratorTest : public BlendfileLoadingBaseTest {
protected:
TestingHierarchyIterator *iterator;
@@ -131,7 +134,7 @@ class USDHierarchyIteratorTest : public BlendfileLoadingBaseTest {
}
};
-TEST_F(USDHierarchyIteratorTest, ExportHierarchyTest)
+TEST_F(AbstractHierarchyIteratorTest, ExportHierarchyTest)
{
/* Load the test blend file. */
if (!blendfile_load("usd/usd_hierarchy_export_test.blend")) {
@@ -206,7 +209,7 @@ TEST_F(USDHierarchyIteratorTest, ExportHierarchyTest)
EXPECT_EQ(expected_data, iterator->data_writers);
}
-TEST_F(USDHierarchyIteratorTest, ExportSubsetTest)
+TEST_F(AbstractHierarchyIteratorTest, ExportSubsetTest)
{
// The scene has no hair or particle systems, and this is already covered by ExportHierarchyTest,
// so not included here. Update this test when hair & particle systems are included.
@@ -317,4 +320,44 @@ TEST_F(USDHierarchyIteratorTest, ExportSubsetTest)
EXPECT_EQ(expected_transforms, iterator->transform_writers);
EXPECT_EQ(expected_data, iterator->data_writers);
}
+
+/* Test class that constructs a depsgraph in such a way that it includes invisible objects. */
+class AbstractHierarchyIteratorInvisibleTest : public AbstractHierarchyIteratorTest {
+ protected:
+ void depsgraph_create(eEvaluationMode depsgraph_evaluation_mode) override
+ {
+ depsgraph = DEG_graph_new(
+ bfile->main, bfile->curscene, bfile->cur_view_layer, depsgraph_evaluation_mode);
+ DEG_graph_build_for_all_objects(depsgraph);
+ BKE_scene_graph_update_tagged(depsgraph, bfile->main);
+ }
+};
+
+TEST_F(AbstractHierarchyIteratorInvisibleTest, ExportInvisibleTest)
+{
+ if (!blendfile_load("alembic/visibility.blend")) {
+ return;
+ }
+ depsgraph_create(DAG_EVAL_RENDER);
+ iterator_create();
+
+ iterator->iterate_and_write();
+
+ // Mapping from object name to set of export paths.
+ used_writers expected_transforms = {{"OBInvisibleAnimatedCube", {"/InvisibleAnimatedCube"}},
+ {"OBInvisibleCube", {"/InvisibleCube"}},
+ {"OBVisibleCube", {"/VisibleCube"}}};
+ EXPECT_EQ(expected_transforms, iterator->transform_writers);
+
+ used_writers expected_data = {{"OBInvisibleAnimatedCube", {"/InvisibleAnimatedCube/Cube"}},
+ {"OBInvisibleCube", {"/InvisibleCube/Cube"}},
+ {"OBVisibleCube", {"/VisibleCube/Cube"}}};
+
+ EXPECT_EQ(expected_data, iterator->data_writers);
+
+ // The scene has no hair or particle systems.
+ EXPECT_EQ(0, iterator->hair_writers.size());
+ EXPECT_EQ(0, iterator->particle_writers.size());
+}
+
} // namespace blender::io
diff --git a/source/blender/io/usd/intern/usd_capi.cc b/source/blender/io/usd/intern/usd_capi.cc
index 98aef62f38e..83b8c18d436 100644
--- a/source/blender/io/usd/intern/usd_capi.cc
+++ b/source/blender/io/usd/intern/usd_capi.cc
@@ -75,8 +75,12 @@ static void export_startjob(void *customdata,
// Construct the depsgraph for exporting.
Scene *scene = DEG_get_input_scene(data->depsgraph);
- ViewLayer *view_layer = DEG_get_input_view_layer(data->depsgraph);
- DEG_graph_build_from_view_layer(data->depsgraph, data->bmain, scene, view_layer);
+ if (data->params.visible_objects_only) {
+ DEG_graph_build_from_view_layer(data->depsgraph);
+ }
+ else {
+ DEG_graph_build_for_all_objects(data->depsgraph);
+ }
BKE_scene_graph_update_tagged(data->depsgraph, data->bmain);
*progress = 0.0f;
@@ -122,7 +126,7 @@ static void export_startjob(void *customdata,
// Update the scene for the next frame to render.
scene->r.cfra = static_cast<int>(frame);
scene->r.subframe = frame - scene->r.cfra;
- BKE_scene_graph_update_for_newframe(data->depsgraph, data->bmain);
+ BKE_scene_graph_update_for_newframe(data->depsgraph);
iter.set_export_frame(frame);
iter.iterate_and_write();
@@ -142,7 +146,7 @@ static void export_startjob(void *customdata,
// Finish up by going back to the keyframe that was current before we started.
if (CFRA != orig_frame) {
CFRA = orig_frame;
- BKE_scene_graph_update_for_newframe(data->depsgraph, data->bmain);
+ BKE_scene_graph_update_for_newframe(data->depsgraph);
}
data->export_ok = true;
diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc
index a416941fb4d..4910b7f11dd 100644
--- a/source/blender/io/usd/intern/usd_writer_abstract.cc
+++ b/source/blender/io/usd/intern/usd_writer_abstract.cc
@@ -114,6 +114,20 @@ pxr::UsdShadeMaterial USDAbstractWriter::ensure_usd_material(Material *material)
return usd_material;
}
+void USDAbstractWriter::write_visibility(const HierarchyContext &context,
+ const pxr::UsdTimeCode timecode,
+ pxr::UsdGeomImageable &usd_geometry)
+{
+ pxr::UsdAttribute attr_visibility = usd_geometry.CreateVisibilityAttr(pxr::VtValue(), true);
+
+ const bool is_visible = context.is_object_visible(
+ usd_export_context_.export_params.evaluation_mode);
+ const pxr::TfToken visibility = is_visible ? pxr::UsdGeomTokens->inherited :
+ pxr::UsdGeomTokens->invisible;
+
+ usd_value_writer_.SetAttribute(attr_visibility, pxr::VtValue(visibility), timecode);
+}
+
} // namespace usd
} // namespace io
} // namespace blender
diff --git a/source/blender/io/usd/intern/usd_writer_abstract.h b/source/blender/io/usd/intern/usd_writer_abstract.h
index a689deaf0d8..248bdd22a3b 100644
--- a/source/blender/io/usd/intern/usd_writer_abstract.h
+++ b/source/blender/io/usd/intern/usd_writer_abstract.h
@@ -72,6 +72,10 @@ class USDAbstractWriter : public AbstractHierarchyWriter {
pxr::UsdTimeCode get_export_time_code() const;
pxr::UsdShadeMaterial ensure_usd_material(Material *material);
+
+ void write_visibility(const HierarchyContext &context,
+ const pxr::UsdTimeCode timecode,
+ pxr::UsdGeomImageable &usd_geometry);
};
} // namespace usd
diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc
index bd2c549e729..75d1ca605d4 100644
--- a/source/blender/io/usd/intern/usd_writer_mesh.cc
+++ b/source/blender/io/usd/intern/usd_writer_mesh.cc
@@ -42,6 +42,8 @@
#include "DNA_object_fluidsim_types.h"
#include "DNA_particle_types.h"
+#include <iostream>
+
namespace blender {
namespace io {
namespace usd {
@@ -52,27 +54,10 @@ USDGenericMeshWriter::USDGenericMeshWriter(const USDExporterContext &ctx) : USDA
bool USDGenericMeshWriter::is_supported(const HierarchyContext *context) const
{
- Object *object = context->object;
- bool is_dupli = context->duplicator != nullptr;
- int base_flag;
-
- if (is_dupli) {
- /* Construct the object's base flags from its dupli-parent, just like is done in
- * deg_objects_dupli_iterator_next(). Without this, the visibility check below will fail. Doing
- * this here, instead of a more suitable location in AbstractHierarchyIterator, prevents
- * copying the Object for every dupli. */
- base_flag = object->base_flag;
- object->base_flag = context->duplicator->base_flag | BASE_FROM_DUPLI;
- }
-
- int visibility = BKE_object_visibility(object,
- usd_export_context_.export_params.evaluation_mode);
-
- if (is_dupli) {
- object->base_flag = base_flag;
+ if (usd_export_context_.export_params.visible_objects_only) {
+ return context->is_object_visible(usd_export_context_.export_params.evaluation_mode);
}
-
- return (visibility & OB_VISIBLE_SELF) != 0;
+ return true;
}
void USDGenericMeshWriter::do_write(HierarchyContext &context)
@@ -169,6 +154,8 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
const pxr::SdfPath &usd_path = usd_export_context_.usd_path;
pxr::UsdGeomMesh usd_mesh = pxr::UsdGeomMesh::Define(stage, usd_path);
+ write_visibility(context, timecode, usd_mesh);
+
USDMeshData usd_mesh_data;
get_geometry_data(mesh, usd_mesh_data);
diff --git a/source/blender/io/usd/usd.h b/source/blender/io/usd/usd.h
index f2826cd1d7c..b9ea90736ff 100644
--- a/source/blender/io/usd/usd.h
+++ b/source/blender/io/usd/usd.h
@@ -35,6 +35,7 @@ struct USDExportParams {
bool export_normals;
bool export_materials;
bool selected_objects_only;
+ bool visible_objects_only;
bool use_instancing;
enum eEvaluationMode evaluation_mode;
};
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 6c4d2856526..3873763e3e0 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -322,6 +322,11 @@ typedef enum eBrushCurvePreset {
BRUSH_CURVE_SMOOTHER = 9,
} eBrushCurvePreset;
+typedef enum eBrushDeformTarget {
+ BRUSH_DEFORM_TARGET_GEOMETRY = 0,
+ BRUSH_DEFORM_TARGET_CLOTH_SIM = 1,
+} eBrushDeformTarget;
+
typedef enum eBrushElasticDeformType {
BRUSH_ELASTIC_DEFORM_GRAB = 0,
BRUSH_ELASTIC_DEFORM_GRAB_BISCALE = 1,
@@ -539,7 +544,7 @@ typedef struct Brush {
/** Source for fill tool color gradient application. */
char gradient_fill_mode;
- char _pad0[1];
+ char _pad0[5];
/** Projection shape (sphere, circle). */
char falloff_shape;
@@ -587,6 +592,8 @@ typedef struct Brush {
/* Maximun distance to search fake neighbors from a vertex. */
float disconnected_distance_max;
+ int deform_target;
+
/* automasking */
int automasking_flags;
int automasking_boundary_edges_propagation_steps;
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index fc50261eb03..b92c9f42a73 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1033,6 +1033,7 @@ typedef enum {
eMultiresModifierFlag_PlainUv_DEPRECATED = (1 << 1),
eMultiresModifierFlag_UseCrease = (1 << 2),
eMultiresModifierFlag_UseCustomNormals = (1 << 3),
+ eMultiresModifierFlag_UseSculptBaseMesh = (1 << 4),
} MultiresModifierFlag;
/* DEPRECATED, only used for versioning. */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 6568281a8d4..62c072831b4 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -537,8 +537,6 @@ enum {
OB_TRANSFLAG_UNUSED_12 = 1 << 12, /* cleared */
/* runtime constraints disable */
OB_NO_CONSTRAINTS = 1 << 13,
- /* hack to work around particle issue */
- OB_NO_PSYS_UPDATE = 1 << 14,
OB_DUPLI = OB_DUPLIVERTS | OB_DUPLICOLLECTION | OB_DUPLIFACES | OB_DUPLIPARTS,
};
diff --git a/source/blender/makesdna/DNA_scene_defaults.h b/source/blender/makesdna/DNA_scene_defaults.h
index ec64eea0aae..69580da8c5f 100644
--- a/source/blender/makesdna/DNA_scene_defaults.h
+++ b/source/blender/makesdna/DNA_scene_defaults.h
@@ -364,4 +364,3 @@
}
/* clang-format off */
-
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index d5b828c898d..e8c4d5cde20 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -68,8 +68,6 @@ typedef struct bScreen {
/** User-setting for which editors get redrawn during anim playback. */
short redraws_flag;
- char statusbar_info[256];
-
/** Temp screen in a temp window, don't save (like user prefs). */
char temp;
/** Temp screen for image render display or fileselect. */
@@ -635,13 +633,21 @@ typedef enum eRegionType {
RGN_TYPE_EXECUTE = 10,
RGN_TYPE_FOOTER = 11,
RGN_TYPE_TOOL_HEADER = 12,
+
+#define RGN_TYPE_LEN (RGN_TYPE_TOOL_HEADER + 1)
} eRegionType;
+
/* use for function args */
#define RGN_TYPE_ANY -1
/* Region supports panel tabs (categories). */
#define RGN_TYPE_HAS_CATEGORY_MASK (1 << RGN_TYPE_UI)
+/* Check for any kind of header region. */
+#define RGN_TYPE_IS_HEADER_ANY(regiontype) \
+ (((1 << (regiontype)) & \
+ ((1 << RGN_TYPE_HEADER) | 1 << (RGN_TYPE_TOOL_HEADER) | (1 << RGN_TYPE_FOOTER))) != 0)
+
/** #ARegion.alignment */
enum {
RGN_ALIGN_NONE = 0,
@@ -661,6 +667,7 @@ enum {
/** Mask out flags so we can check the alignment. */
#define RGN_ALIGN_ENUM_FROM_MASK(align) ((align) & ((1 << 4) - 1))
+#define RGN_ALIGN_FLAG_FROM_MASK(align) ((align) & ~((1 << 4) - 1))
/** #ARegion.flag */
enum {
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index c2ed6c97d3d..136fe3744ef 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -689,16 +689,17 @@ typedef struct UserDef {
int audioformat;
int audiochannels;
- /** Setting for UI scale. */
+ /** Setting for UI scale (fractional), before screen DPI has been applied. */
float ui_scale;
/** Setting for UI line width. */
int ui_line_width;
/** Runtime, full DPI divided by `pixelsize`. */
int dpi;
- /** Runtime, multiplier to scale UI elements based on DPI. */
+ /** Runtime, multiplier to scale UI elements based on DPI (fractional). */
float dpi_fac;
+ /** Runtime, `1.0 / dpi_fac` */
float inv_dpi_fac;
- /** Runtime, line width and point size based on DPI. */
+ /** Runtime, calculated from line-width and point-size based on DPI (rounded to int). */
float pixelsize;
/** Deprecated, for forward compatibility. */
int virtual_pixel;
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 0b43a5a6653..1896813bdb3 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -47,7 +47,6 @@ set(DEFSRC
rna_fluid.c
rna_gpencil.c
rna_gpencil_modifier.c
- rna_hair.c
rna_image.c
rna_key.c
rna_lattice.c
@@ -69,7 +68,6 @@ set(DEFSRC
rna_packedfile.c
rna_palette.c
rna_particle.c
- rna_pointcloud.c
rna_pose.c
rna_render.c
rna_rigidbody.c
@@ -79,7 +77,6 @@ set(DEFSRC
rna_sculpt_paint.c
rna_sequencer.c
rna_shader_fx.c
- rna_simulation.c
rna_sound.c
rna_space.c
rna_speaker.c
@@ -99,6 +96,16 @@ set(DEFSRC
rna_xr.c
)
+if(WITH_EXPERIMENTAL_FEATURES)
+ add_definitions(-DWITH_PARTICLE_NODES)
+ add_definitions(-DWITH_HAIR_NODES)
+ list(APPEND DEFSRC
+ rna_pointcloud.c
+ rna_simulation.c
+ rna_hair.c
+ )
+endif()
+
set(APISRC
rna_action_api.c
rna_animation_api.c
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 779e4363be0..2b1e5b3c702 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -599,7 +599,7 @@ static void rna_float_print(FILE *f, float num)
else if (num == FLT_MAX) {
fprintf(f, "FLT_MAX");
}
- else if ((fabsf(num) < INT64_MAX) && ((int64_t)num == num)) {
+ else if ((fabsf(num) < (float)INT64_MAX) && ((int64_t)num == num)) {
fprintf(f, "%.1ff", num);
}
else {
@@ -4285,7 +4285,9 @@ static RNAProcessItem PROCESS_ITEMS[] = {
{"rna_dynamicpaint.c", NULL, RNA_def_dynamic_paint},
{"rna_fcurve.c", "rna_fcurve_api.c", RNA_def_fcurve},
{"rna_gpencil.c", NULL, RNA_def_gpencil},
+#ifdef WITH_HAIR_NODES
{"rna_hair.c", NULL, RNA_def_hair},
+#endif
{"rna_image.c", "rna_image_api.c", RNA_def_image},
{"rna_key.c", NULL, RNA_def_key},
{"rna_light.c", NULL, RNA_def_light},
@@ -4308,7 +4310,9 @@ static RNAProcessItem PROCESS_ITEMS[] = {
{"rna_packedfile.c", NULL, RNA_def_packedfile},
{"rna_palette.c", NULL, RNA_def_palette},
{"rna_particle.c", NULL, RNA_def_particle},
+#ifdef WITH_PARTICLE_NODES
{"rna_pointcloud.c", NULL, RNA_def_pointcloud},
+#endif
{"rna_pose.c", "rna_pose_api.c", RNA_def_pose},
{"rna_curveprofile.c", NULL, RNA_def_profile},
{"rna_lightprobe.c", NULL, RNA_def_lightprobe},
@@ -4318,7 +4322,9 @@ static RNAProcessItem PROCESS_ITEMS[] = {
{"rna_screen.c", NULL, RNA_def_screen},
{"rna_sculpt_paint.c", NULL, RNA_def_sculpt_paint},
{"rna_sequencer.c", "rna_sequencer_api.c", RNA_def_sequencer},
+#ifdef WITH_PARTICLE_NODES
{"rna_simulation.c", NULL, RNA_def_simulation},
+#endif
{"rna_space.c", "rna_space_api.c", RNA_def_space},
{"rna_speaker.c", NULL, RNA_def_speaker},
{"rna_test.c", NULL, RNA_def_test},
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index e9ca0d577ce..f1c125fcbb9 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -251,9 +251,11 @@ short RNA_type_to_ID_code(const StructRNA *type)
if (base_type == &RNA_FreestyleLineStyle) {
return ID_LS;
}
+# ifdef WITH_HAIR_NODES
if (base_type == &RNA_Hair) {
return ID_HA;
}
+# endif
if (base_type == &RNA_Lattice) {
return ID_LT;
}
@@ -287,9 +289,11 @@ short RNA_type_to_ID_code(const StructRNA *type)
if (base_type == &RNA_PaintCurve) {
return ID_PC;
}
+# ifdef WITH_PARTICLE_NODES
if (base_type == &RNA_PointCloud) {
return ID_PT;
}
+# endif
if (base_type == &RNA_LightProbe) {
return ID_LP;
}
@@ -299,9 +303,11 @@ short RNA_type_to_ID_code(const StructRNA *type)
if (base_type == &RNA_Screen) {
return ID_SCR;
}
+# ifdef WITH_PARTICLE_NODES
if (base_type == &RNA_Simulation) {
return ID_SIM;
}
+# endif
if (base_type == &RNA_Sound) {
return ID_SO;
}
@@ -355,7 +361,11 @@ StructRNA *ID_code_to_RNA_type(short idcode)
case ID_GR:
return &RNA_Collection;
case ID_HA:
+# ifdef WITH_HAIR_NODES
return &RNA_Hair;
+# else
+ return &RNA_ID;
+# endif
case ID_IM:
return &RNA_Image;
case ID_KE:
@@ -389,7 +399,11 @@ StructRNA *ID_code_to_RNA_type(short idcode)
case ID_PC:
return &RNA_PaintCurve;
case ID_PT:
+# ifdef WITH_PARTICLE_NODES
return &RNA_PointCloud;
+# else
+ return &RNA_ID;
+# endif
case ID_LP:
return &RNA_LightProbe;
case ID_SCE:
@@ -397,7 +411,11 @@ StructRNA *ID_code_to_RNA_type(short idcode)
case ID_SCR:
return &RNA_Screen;
case ID_SIM:
+# ifdef WITH_PARTICLE_NODES
return &RNA_Simulation;
+# else
+ return &RNA_ID;
+# endif
case ID_SO:
return &RNA_Sound;
case ID_SPK:
diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c
index 0a739dcfc5a..ac4553349cc 100644
--- a/source/blender/makesrna/intern/rna_access_compare_override.c
+++ b/source/blender/makesrna/intern/rna_access_compare_override.c
@@ -484,13 +484,13 @@ static bool rna_property_override_operation_apply(Main *bmain,
/* Special case for IDProps, we use default callback then. */
if (prop_dst->magic != RNA_MAGIC) {
override_apply = rna_property_override_apply_default;
- if (prop_src->magic == RNA_MAGIC && prop_src->override_apply != override_apply) {
+ if (prop_src->magic == RNA_MAGIC && !ELEM(prop_src->override_apply, NULL, override_apply)) {
override_apply = NULL;
}
}
else if (prop_src->magic != RNA_MAGIC) {
override_apply = rna_property_override_apply_default;
- if (prop_dst->override_apply != override_apply) {
+ if (!ELEM(prop_dst->override_apply, NULL, override_apply)) {
override_apply = NULL;
}
}
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 8454d5c125f..155943b3b8d 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -1264,6 +1264,7 @@ static void rna_def_edit_bone(BlenderRNA *brna)
prop = RNA_def_property(srna, "head", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "head");
+ RNA_def_property_ui_range(prop, 0, FLT_MAX, 10, RNA_TRANSLATION_PREC_DEFAULT);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Head", "Location of head end of the bone");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -1271,6 +1272,7 @@ static void rna_def_edit_bone(BlenderRNA *brna)
prop = RNA_def_property(srna, "tail", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_float_sdna(prop, NULL, "tail");
+ RNA_def_property_ui_range(prop, 0, FLT_MAX, 10, RNA_TRANSLATION_PREC_DEFAULT);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Tail", "Location of tail end of the bone");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index a3fa4fed575..f48a7e6715d 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -45,6 +45,18 @@ static const EnumPropertyItem prop_direction_items[] = {
{0, NULL, 0, NULL, NULL},
};
+#ifdef RNA_RUNTIME
+static const EnumPropertyItem prop_smooth_direction_items[] = {
+ {0, "SMOOTH", ICON_ADD, "Smooth", "Smooth the surfae"},
+ {BRUSH_DIR_IN,
+ "ENHANCE_DETAILS",
+ ICON_REMOVE,
+ "Enhance Details",
+ "Enhance the surface detail"},
+ {0, NULL, 0, NULL, NULL},
+};
+#endif
+
static const EnumPropertyItem sculpt_stroke_method_items[] = {
{0, "DOTS", 0, "Dots", "Apply paint on each mouse move step"},
{BRUSH_DRAG_DOT, "DRAG_DOT", 0, "Drag Dot", "Allows a single dot to be carefully positioned"},
@@ -527,6 +539,7 @@ static bool rna_BrushCapabilitiesSculpt_has_direction_get(PointerRNA *ptr)
SCULPT_TOOL_DRAW_SHARP,
SCULPT_TOOL_CLAY,
SCULPT_TOOL_CLAY_STRIPS,
+ SCULPT_TOOL_SMOOTH,
SCULPT_TOOL_LAYER,
SCULPT_TOOL_INFLATE,
SCULPT_TOOL_BLOB,
@@ -795,7 +808,8 @@ static const EnumPropertyItem *rna_Brush_direction_itemf(bContext *C,
case SCULPT_TOOL_CLAY:
case SCULPT_TOOL_CLAY_STRIPS:
return prop_direction_items;
-
+ case SCULPT_TOOL_SMOOTH:
+ return prop_smooth_direction_items;
case SCULPT_TOOL_MASK:
switch ((BrushMaskTool)me->mask_tool) {
case BRUSH_MASK_DRAW:
@@ -1967,6 +1981,20 @@ static void rna_def_brush(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem brush_deformation_target_items[] = {
+ {BRUSH_DEFORM_TARGET_GEOMETRY,
+ "GEOMETRY",
+ 0,
+ "Geometry",
+ "Brush deformation displaces the vertices of the mesh"},
+ {BRUSH_DEFORM_TARGET_CLOTH_SIM,
+ "CLOTH_SIM",
+ 0,
+ "Cloth Simulation",
+ "Brush deforms the mesh by deforming the constraints of a cloth simulation"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
static const EnumPropertyItem brush_elastic_deform_type_items[] = {
{BRUSH_ELASTIC_DEFORM_GRAB, "GRAB", 0, "Grab", ""},
{BRUSH_ELASTIC_DEFORM_GRAB_BISCALE, "GRAB_BISCALE", 0, "Bi-scale Grab", ""},
@@ -2195,6 +2223,12 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Curve Preset", "");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "deform_target", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, brush_deformation_target_items);
+ RNA_def_property_ui_text(
+ prop, "Deformation Target", "How the deformation of the brush will affect the object");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "elastic_deform_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, brush_elastic_deform_type_items);
RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index c8d16ab65cc..9bcf2b81557 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -106,7 +106,7 @@ static const EnumPropertyItem rna_enum_keyframe_type_items[] = {
};
static const EnumPropertyItem rna_enum_onion_keyframe_type_items[] = {
- {-1, "ALL", ICON_ACTION, "All Types", "Include all Keyframe types"},
+ {-1, "ALL", 0, "All", "Include all Keyframe types"},
{BEZT_KEYTYPE_KEYFRAME,
"KEYFRAME",
ICON_KEYTYPE_KEYFRAME_VEC,
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 8045279eef2..6254e40a410 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -455,10 +455,16 @@ void RNA_def_main_cachefiles(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_paintcurves(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_workspaces(BlenderRNA *brna, PropertyRNA *cprop);
void RNA_def_main_lightprobes(BlenderRNA *brna, PropertyRNA *cprop);
+#ifdef WITH_PARTICLE_NODES
void RNA_def_main_hairs(BlenderRNA *brna, PropertyRNA *cprop);
+#endif
+#ifdef WITH_HAIR_NODES
void RNA_def_main_pointclouds(BlenderRNA *brna, PropertyRNA *cprop);
+#endif
void RNA_def_main_volumes(BlenderRNA *brna, PropertyRNA *cprop);
+#ifdef WITH_PARTICLE_NODES
void RNA_def_main_simulations(BlenderRNA *brna, PropertyRNA *cprop);
+#endif
/* ID Properties */
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 97702b06b6f..d83fca69278 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -109,7 +109,9 @@ RNA_MAIN_LISTBASE_FUNCS_DEF(collections)
RNA_MAIN_LISTBASE_FUNCS_DEF(curves)
RNA_MAIN_LISTBASE_FUNCS_DEF(fonts)
RNA_MAIN_LISTBASE_FUNCS_DEF(gpencils)
+# ifdef WITH_HAIR_NODES
RNA_MAIN_LISTBASE_FUNCS_DEF(hairs)
+# endif
RNA_MAIN_LISTBASE_FUNCS_DEF(images)
RNA_MAIN_LISTBASE_FUNCS_DEF(lattices)
RNA_MAIN_LISTBASE_FUNCS_DEF(libraries)
@@ -126,11 +128,15 @@ RNA_MAIN_LISTBASE_FUNCS_DEF(objects)
RNA_MAIN_LISTBASE_FUNCS_DEF(paintcurves)
RNA_MAIN_LISTBASE_FUNCS_DEF(palettes)
RNA_MAIN_LISTBASE_FUNCS_DEF(particles)
+# ifdef WITH_PARTICLE_NODES
RNA_MAIN_LISTBASE_FUNCS_DEF(pointclouds)
+# endif
RNA_MAIN_LISTBASE_FUNCS_DEF(scenes)
RNA_MAIN_LISTBASE_FUNCS_DEF(screens)
RNA_MAIN_LISTBASE_FUNCS_DEF(shapekeys)
+# ifdef WITH_PARTICLE_NODES
RNA_MAIN_LISTBASE_FUNCS_DEF(simulations)
+# endif
RNA_MAIN_LISTBASE_FUNCS_DEF(sounds)
RNA_MAIN_LISTBASE_FUNCS_DEF(speakers)
RNA_MAIN_LISTBASE_FUNCS_DEF(texts)
@@ -384,25 +390,31 @@ void RNA_def_main(BlenderRNA *brna)
"LightProbes",
"LightProbe data-blocks",
RNA_def_main_lightprobes},
+# ifdef WITH_HAIR_NODES
{"hairs", "Hair", "rna_Main_hairs_begin", "Hairs", "Hair data-blocks", RNA_def_main_hairs},
+# endif
+# ifdef WITH_PARTICLE_NODES
{"pointclouds",
"PointCloud",
"rna_Main_pointclouds_begin",
"Point Clouds",
"Point cloud data-blocks",
RNA_def_main_pointclouds},
+# endif
{"volumes",
"Volume",
"rna_Main_volumes_begin",
"Volumes",
"Volume data-blocks",
RNA_def_main_volumes},
+# ifdef WITH_PARTICLE_NODES
{"simulations",
"Simulation",
"rna_Main_simulations_begin",
"Simulations",
"Simulation data-blocks",
RNA_def_main_simulations},
+# endif
{NULL, NULL, NULL, NULL, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 990a5412093..7c941ddb524 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -708,6 +708,7 @@ static bGPdata *rna_Main_gpencils_new(Main *bmain, const char *name)
return gpd;
}
+# ifdef WITH_HAIR_NODES
static Hair *rna_Main_hairs_new(Main *bmain, const char *name)
{
char safe_name[MAX_ID_NAME - 2];
@@ -717,7 +718,9 @@ static Hair *rna_Main_hairs_new(Main *bmain, const char *name)
id_us_min(&hair->id);
return hair;
}
+# endif
+# ifdef WITH_PARTICLE_NODES
static PointCloud *rna_Main_pointclouds_new(Main *bmain, const char *name)
{
char safe_name[MAX_ID_NAME - 2];
@@ -727,6 +730,7 @@ static PointCloud *rna_Main_pointclouds_new(Main *bmain, const char *name)
id_us_min(&pointcloud->id);
return pointcloud;
}
+# endif
static Volume *rna_Main_volumes_new(Main *bmain, const char *name)
{
@@ -738,6 +742,7 @@ static Volume *rna_Main_volumes_new(Main *bmain, const char *name)
return volume;
}
+# ifdef WITH_PARTICLE_NODES
static Simulation *rna_Main_simulations_new(Main *bmain, const char *name)
{
char safe_name[MAX_ID_NAME - 2];
@@ -747,6 +752,7 @@ static Simulation *rna_Main_simulations_new(Main *bmain, const char *name)
id_us_min(&simulation->id);
return simulation;
}
+# endif
/* tag functions, all the same */
# define RNA_MAIN_ID_TAG_FUNCS_DEF(_func_name, _listbase_name, _id_type) \
@@ -790,10 +796,16 @@ RNA_MAIN_ID_TAG_FUNCS_DEF(cachefiles, cachefiles, ID_CF)
RNA_MAIN_ID_TAG_FUNCS_DEF(paintcurves, paintcurves, ID_PC)
RNA_MAIN_ID_TAG_FUNCS_DEF(workspaces, workspaces, ID_WS)
RNA_MAIN_ID_TAG_FUNCS_DEF(lightprobes, lightprobes, ID_LP)
+# ifdef WITH_HAIR_NODES
RNA_MAIN_ID_TAG_FUNCS_DEF(hairs, hairs, ID_HA)
+# endif
+# ifdef WITH_PARTICLE_NODES
RNA_MAIN_ID_TAG_FUNCS_DEF(pointclouds, pointclouds, ID_PT)
+# endif
RNA_MAIN_ID_TAG_FUNCS_DEF(volumes, volumes, ID_VO)
+# ifdef WITH_PARTICLE_NODES
RNA_MAIN_ID_TAG_FUNCS_DEF(simulations, simulations, ID_SIM)
+# endif
# undef RNA_MAIN_ID_TAG_FUNCS_DEF
@@ -2194,6 +2206,7 @@ void RNA_def_main_lightprobes(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
}
+# ifdef WITH_HAIR_NODES
void RNA_def_main_hairs(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
@@ -2237,7 +2250,9 @@ void RNA_def_main_hairs(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_boolean(func, "value", 0, "Value", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
}
+# endif
+# ifdef WITH_PARTICLE_NODES
void RNA_def_main_pointclouds(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
@@ -2284,6 +2299,7 @@ void RNA_def_main_pointclouds(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_boolean(func, "value", 0, "Value", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
}
+# endif
void RNA_def_main_volumes(BlenderRNA *brna, PropertyRNA *cprop)
{
@@ -2329,6 +2345,7 @@ void RNA_def_main_volumes(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
}
+# ifdef WITH_PARTICLE_NODES
void RNA_def_main_simulations(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
@@ -2368,5 +2385,6 @@ void RNA_def_main_simulations(BlenderRNA *brna, PropertyRNA *cprop)
parm = RNA_def_boolean(func, "value", 0, "Value", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
}
+# endif
#endif
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index f95899262d3..0338a094d14 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -723,7 +723,9 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
case eModifierType_WeightedNormal:
return &RNA_WeightedNormalModifier;
case eModifierType_Simulation:
+# ifdef WITH_PARTICLE_NODES
return &RNA_SimulationModifier;
+# endif
/* Default */
case eModifierType_Fluidsim: /* deprecated */
case eModifierType_None:
@@ -1630,6 +1632,7 @@ static void rna_ParticleInstanceModifier_particle_system_set(PointerRNA *ptr,
CLAMP_MIN(psmd->psys, 1);
}
+# ifdef WITH_PARTICLE_NODES
static void rna_SimulationModifier_simulation_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
SimulationModifierData *smd = ptr->data;
@@ -1672,6 +1675,7 @@ static void rna_SimulationModifier_data_path_set(PointerRNA *ptr, const char *va
smd->data_path = NULL;
}
}
+# endif
/**
* Special set callback that just changes the first bit of the expansion flag.
@@ -2076,6 +2080,14 @@ static void rna_def_modifier_multires(BlenderRNA *brna)
prop, "Use Custom Normals", "Interpolates existing custom normals to resulting mesh");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "use_sculpt_base_mesh", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", eMultiresModifierFlag_UseSculptBaseMesh);
+ RNA_def_property_ui_text(prop,
+ "Sculpt Base Mesh",
+ "Make Sculpt Mode tools deform the base mesh while previewing the "
+ "displacement of higher subdivision levels");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
RNA_define_lib_overridable(false);
}
@@ -6999,6 +7011,7 @@ static void rna_def_modifier_weightednormal(BlenderRNA *brna)
RNA_define_lib_overridable(false);
}
+# ifdef WITH_PARTICLE_NODES
static void rna_def_modifier_simulation(BlenderRNA *brna)
{
StructRNA *srna;
@@ -7027,6 +7040,7 @@ static void rna_def_modifier_simulation(BlenderRNA *brna)
RNA_define_lib_overridable(false);
}
+# endif
void RNA_def_modifier(BlenderRNA *brna)
{
@@ -7156,7 +7170,9 @@ void RNA_def_modifier(BlenderRNA *brna)
rna_def_modifier_meshseqcache(brna);
rna_def_modifier_surfacedeform(brna);
rna_def_modifier_weightednormal(brna);
+# ifdef WITH_PARTICLE_NODES
rna_def_modifier_simulation(brna);
+# endif
}
#endif
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 08ca3f16b6d..39e1f17d33d 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -570,9 +570,17 @@ static StructRNA *rna_Object_data_typef(PointerRNA *ptr)
case OB_GPENCIL:
return &RNA_GreasePencil;
case OB_HAIR:
+# ifdef WITH_HAIR_NODES
return &RNA_Hair;
+# else
+ return &RNA_ID;
+# endif
case OB_POINTCLOUD:
+# ifdef WITH_PARTICLE_NODES
return &RNA_PointCloud;
+# else
+ return &RNA_ID;
+# endif
case OB_VOLUME:
return &RNA_Volume;
default:
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 5d266e910ad..3ec7963a81e 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -924,6 +924,23 @@ static void rna_Scene_volume_update(Main *UNUSED(bmain), Scene *UNUSED(scene), P
DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO_VOLUME | ID_RECALC_SEQUENCER_STRIPS);
}
+static const char *rna_Scene_statistics_string_get(Scene *scene,
+ Main *bmain,
+ ReportList *reports,
+ ViewLayer *view_layer)
+{
+ if (BKE_scene_find_from_view_layer(bmain, view_layer) != scene) {
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "View Layer '%s' not found in scene '%s'",
+ view_layer->name,
+ scene->id.name + 2);
+ return "";
+ }
+
+ return ED_info_statistics_string(bmain, scene, view_layer);
+}
+
static void rna_Scene_framelen_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
{
scene->r.framelen = (float)scene->r.framapto / (float)scene->r.images;
@@ -7277,6 +7294,9 @@ void RNA_def_scene(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
+ PropertyRNA *parm;
+
static const EnumPropertyItem audio_distance_model_items[] = {
{0, "NONE", 0, "None", "No distance attenuation"},
{1, "INVERSE", 0, "Inverse", "Inverse distance model"},
@@ -7668,6 +7688,14 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE, NULL);
RNA_def_property_update(prop, NC_SCENE, "rna_Scene_volume_update");
+ /* Statistics */
+ func = RNA_def_function(srna, "statistics", "rna_Scene_statistics_string_get");
+ RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS);
+ parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "View Layer", "");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_string(func, "statistics", NULL, 0, "Statistics", "");
+ RNA_def_function_return(func, parm);
+
/* Grease Pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 06c73fbb19c..d258677c606 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -73,7 +73,7 @@ static void rna_Scene_frame_set(Scene *scene, Main *bmain, int frame, float subf
for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL;
view_layer = view_layer->next) {
Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true);
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
# ifdef WITH_PYTHON
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index fb2a60db0fd..ab84dcb0aba 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -288,9 +288,11 @@ static void rna_View2D_view_to_region(
}
}
-static const char *rna_Screen_statusbar_info_get(struct bScreen *screen, Main *bmain, bContext *C)
+static const char *rna_Screen_statusbar_info_get(struct bScreen *UNUSED(screen),
+ Main *bmain,
+ bContext *C)
{
- return ED_info_statusbar_string(bmain, screen, C);
+ return ED_info_statusbar_string(bmain, CTX_data_scene(C), CTX_data_view_layer(C));
}
#else
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 0cfc6fd569c..629dc104ab5 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -637,6 +637,8 @@ static void rna_Sequence_name_set(PointerRNA *ptr, const char *value)
char oldname[sizeof(seq->name)];
AnimData *adt;
+ BKE_sequencer_prefetch_stop(scene);
+
/* make a copy of the old name first */
BLI_strncpy(oldname, seq->name + 2, sizeof(seq->name) - 2);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 9f259aba0c7..03a70be6def 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -1297,15 +1297,13 @@ static const EnumPropertyItem *rna_3DViewShading_render_pass_itemf(bContext *C,
{
Scene *scene = CTX_data_scene(C);
- const bool ao_enabled = scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED;
const bool bloom_enabled = scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED;
int totitem = 0;
EnumPropertyItem *result = NULL;
for (int i = 0; rna_enum_view3dshading_render_pass_type_items[i].identifier != NULL; i++) {
const EnumPropertyItem *item = &rna_enum_view3dshading_render_pass_type_items[i];
- if (!((!ao_enabled && item->value == EEVEE_RENDER_PASS_AO) ||
- (!bloom_enabled &&
+ if (!((!bloom_enabled &&
(item->value == EEVEE_RENDER_PASS_BLOOM || STREQ(item->name, "Effects"))))) {
RNA_enum_item_add(&result, &totitem, item);
}
@@ -1321,9 +1319,6 @@ static int rna_3DViewShading_render_pass_get(PointerRNA *ptr)
eViewLayerEEVEEPassType result = shading->render_pass;
Scene *scene = rna_3DViewShading_scene(ptr);
- if (result == EEVEE_RENDER_PASS_AO && ((scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0)) {
- result = EEVEE_RENDER_PASS_COMBINED;
- }
if (result == EEVEE_RENDER_PASS_BLOOM && ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) {
result = EEVEE_RENDER_PASS_COMBINED;
}
@@ -2122,6 +2117,7 @@ static void rna_SpaceNodeEditor_node_tree_update(const bContext *C, PointerRNA *
ED_node_tree_update(C);
}
+# ifdef WITH_PARTICLE_NODES
static PointerRNA rna_SpaceNodeEditor_simulation_get(PointerRNA *ptr)
{
SpaceNode *snode = (SpaceNode *)ptr->data;
@@ -2153,6 +2149,7 @@ static void rna_SpaceNodeEditor_simulation_set(PointerRNA *ptr,
}
snode->id = &sim->id;
}
+# endif
static int rna_SpaceNodeEditor_tree_type_get(PointerRNA *ptr)
{
@@ -4796,7 +4793,7 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Waveform Displaying", "How Waveforms are drawn");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
- prop = RNA_def_property(srna, "zoom_to_fit", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_zoom_to_fit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_ZOOM_TO_FIT);
RNA_def_property_ui_text(
prop, "Zoom to Fit", "Automatically zoom preview image to make it fully fit the region");
@@ -6213,6 +6210,7 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "ID From", "Data-block from which the edited data-block is linked");
+# ifdef WITH_PARTICLE_NODES
prop = RNA_def_property(srna, "simulation", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Simulation");
@@ -6223,6 +6221,7 @@ static void rna_def_space_node(BlenderRNA *brna)
NULL,
NULL);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE, NULL);
+# endif
prop = RNA_def_property(srna, "path", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "treepath", NULL);
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index 7853bc4acac..9ced297bb48 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -238,7 +238,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Needed when rendering or baking will in sculpt mode. */
const bool for_render = (ctx->flag & MOD_APPLY_RENDER) != 0;
- if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render) {
+ const bool sculpt_base_mesh = mmd->flags & eMultiresModifierFlag_UseSculptBaseMesh;
+
+ if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render && !sculpt_base_mesh) {
/* NOTE: CCG takes ownership over Subdiv. */
result = multires_as_ccg(mmd, ctx, mesh, subdiv);
result->runtime.subdiv_ccg_tot_level = mmd->totlvl;
@@ -341,6 +343,12 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemR(col, &ptr, "sculpt_levels", 0, IFACE_("Sculpt"), ICON_NONE);
uiItemR(col, &ptr, "render_levels", 0, IFACE_("Render"), ICON_NONE);
+ const bool is_sculpt_mode = CTX_data_active_object(C)->mode & OB_MODE_SCULPT;
+ uiBlock *block = uiLayoutGetBlock(panel->layout);
+ UI_block_lock_set(block, !is_sculpt_mode, IFACE_("Sculpt Base Mesh"));
+ uiItemR(col, &ptr, "use_sculpt_base_mesh", 0, IFACE_("Sculpt Base Mesh"), ICON_NONE);
+ UI_block_lock_clear(block);
+
uiItemR(layout, &ptr, "show_only_control_edges", 0, NULL, ICON_NONE);
modifier_panel_end(layout, &ptr);
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index ea0c63da1b0..4ef1b19dc64 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -219,7 +219,7 @@ static void deformVerts(ModifierData *md,
psmd->totdmedge = psmd->mesh_final->totedge;
psmd->totdmface = psmd->mesh_final->totface;
- if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) {
+ {
struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
psmd->flag &= ~eParticleSystemFlag_psys_updated;
particle_system_update(
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index 7bcf96116b9..e1e0d01055a 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -50,12 +50,6 @@ void BPY_pyconstraint_update(struct Object *owner, struct bConstraint *con);
int BPY_is_pyconstraint(struct Text *text);
// void BPY_free_pyconstraint_links(struct Text *text);
-void BPY_python_start(int argc, const char **argv);
-void BPY_python_end(void);
-void BPY_python_reset(struct bContext *C);
-void BPY_python_use_system_env(void);
-void BPY_python_backtrace(/* FILE */ void *file);
-
/* global interpreter lock */
typedef void *BPy_ThreadStatePtr;
@@ -73,40 +67,6 @@ void BPY_thread_restore(BPy_ThreadStatePtr tstate);
} \
(void)0
-bool BPY_execute_filepath(struct bContext *C, const char *filepath, struct ReportList *reports);
-bool BPY_execute_text(struct bContext *C,
- struct Text *text,
- struct ReportList *reports,
- const bool do_jump);
-
-bool BPY_execute_string_as_number(struct bContext *C,
- const char *imports[],
- const char *expr,
- const char *report_prefix,
- double *r_value);
-bool BPY_execute_string_as_intptr(struct bContext *C,
- const char *imports[],
- const char *expr,
- const char *report_prefix,
- intptr_t *r_value);
-bool BPY_execute_string_as_string_and_size(struct bContext *C,
- const char *imports[],
- const char *expr,
- const char *report_prefix,
- char **r_value,
- size_t *r_value_size);
-bool BPY_execute_string_as_string(struct bContext *C,
- const char *imports[],
- const char *expr,
- const char *report_prefix,
- char **r_value);
-
-bool BPY_execute_string_ex(struct bContext *C,
- const char *imports[],
- const char *expr,
- bool use_eval);
-bool BPY_execute_string(struct bContext *C, const char *imports[], const char *expr);
-
void BPY_text_free_code(struct Text *text);
void BPY_modules_update(
struct bContext *C); // XXX - annoying, need this for pointers that get out of date
diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/python/BPY_extern_python.h
index 0f89fbda737..348f6986863 100644
--- a/source/blender/gpu/intern/gpu_shader_private.h
+++ b/source/blender/python/BPY_extern_python.h
@@ -15,40 +15,29 @@
*/
/** \file
- * \ingroup gpu
+ * \ingroup python
+ *
+ * Functionality relating to Python setup & tear down.
*/
#pragma once
-#include "GPU_shader_interface.h"
+struct bContext;
#ifdef __cplusplus
extern "C" {
#endif
-struct GPUShader {
- /** Handle for full program (links shader stages below). */
- GLuint program;
-
- /** Handle for vertex shader. */
- GLuint vertex;
- /** Handle for geometry shader. */
- GLuint geometry;
- /** Handle for fragment shader. */
- GLuint fragment;
-
- /** Cached uniform & attribute interface for shader. */
- GPUShaderInterface *interface;
-
- int feedback_transform_type;
-#ifndef NDEBUG
- char name[64];
-#endif
-};
+/* For 'FILE'. */
+#include <stdio.h>
-/* XXX do not use it. Special hack to use OCIO with batch API. */
-GPUShader *immGetShader(void);
+/* bpy_interface.c */
+void BPY_python_start(int argc, const char **argv);
+void BPY_python_end(void);
+void BPY_python_reset(struct bContext *C);
+void BPY_python_use_system_env(void);
+void BPY_python_backtrace(FILE *file);
#ifdef __cplusplus
-}
+} /* extern "C" */
#endif
diff --git a/source/blender/python/BPY_extern_run.h b/source/blender/python/BPY_extern_run.h
new file mode 100644
index 00000000000..5f12ada4ff2
--- /dev/null
+++ b/source/blender/python/BPY_extern_run.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup python
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "BLI_sys_types.h"
+
+struct ReportList;
+struct Text;
+struct bContext;
+
+/* bpy_interface_run.c */
+bool BPY_run_filepath(struct bContext *C, const char *filepath, struct ReportList *reports);
+bool BPY_run_text(struct bContext *C,
+ struct Text *text,
+ struct ReportList *reports,
+ const bool do_jump);
+
+/* Use the 'eval' for simple single-line expressions,
+ * otherwise 'exec' for full multi-line scripts. */
+bool BPY_run_string_exec(struct bContext *C, const char *imports[], const char *expr);
+bool BPY_run_string_eval(struct bContext *C, const char *imports[], const char *expr);
+
+/* Run, evaluating to fixed type result. */
+bool BPY_run_string_as_number(struct bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ double *r_value);
+bool BPY_run_string_as_intptr(struct bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ intptr_t *r_value);
+bool BPY_run_string_as_string_and_size(struct bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ char **r_value,
+ size_t *r_value_size);
+bool BPY_run_string_as_string(struct bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ char **r_value);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index e39b5faf3c4..04bceb17c20 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -1134,7 +1134,7 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject
return NULL;
}
- me_eval = mesh_create_eval_final_render(depsgraph, scene_eval, ob_eval, &data_masks);
+ me_eval = mesh_create_eval_final(depsgraph, scene_eval, ob_eval, &data_masks);
}
else {
if (use_cage) {
diff --git a/source/blender/python/generic/CMakeLists.txt b/source/blender/python/generic/CMakeLists.txt
index 785c1d66407..dce6a7e1c91 100644
--- a/source/blender/python/generic/CMakeLists.txt
+++ b/source/blender/python/generic/CMakeLists.txt
@@ -32,18 +32,18 @@ set(INC_SYS
set(SRC
bgl.c
+ bl_math_py_api.c
blf_py_api.c
bpy_threads.c
idprop_py_api.c
imbuf_py_api.c
- bl_math_py_api.c
py_capi_utils.c
bgl.h
+ bl_math_py_api.h
blf_py_api.h
idprop_py_api.h
imbuf_py_api.h
- bl_math_py_api.h
py_capi_utils.h
# header-only
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index caae5c4e122..838a1239210 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -382,20 +382,6 @@ void PyC_StackSpit(void)
PyGILState_Release(gilstate);
}
-void PyC_StackPrint(/* FILE */ void *fp)
-{
- PyThreadState *tstate = PyGILState_GetThisThreadState();
- if (tstate != NULL && tstate->frame != NULL) {
- PyFrameObject *frame = tstate->frame;
- do {
- const int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti);
- const char *filename = _PyUnicode_AsString(frame->f_code->co_filename);
- const char *funcname = _PyUnicode_AsString(frame->f_code->co_name);
- fprintf(fp, " File \"%s\", line %d in %s\n", filename, line, funcname);
- } while ((frame = frame->f_back));
- }
-}
-
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index dde450012d0..e8b2e8ff502 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -28,7 +28,6 @@ void PyC_ObSpit(const char *name, PyObject *var);
void PyC_ObSpitStr(char *result, size_t result_len, PyObject *var);
void PyC_LineSpit(void);
void PyC_StackSpit(void);
-void PyC_StackPrint(/* FILE */ void *fp);
PyObject *PyC_ExceptionBuffer(void);
PyObject *PyC_ExceptionBuffer_Simple(void);
PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...);
diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c
index 165286c3661..c1a6ce09d37 100644
--- a/source/blender/python/gpu/gpu_py_shader.c
+++ b/source/blender/python/gpu/gpu_py_shader.c
@@ -604,7 +604,8 @@ PyDoc_STRVAR(
" ``GPU_ATI``, ``GPU_NVIDIA`` and ``GPU_INTEL``.\n"
"\n"
" The following extensions are enabled by default if supported by the GPU:\n"
- " ``GL_ARB_texture_gather`` and ``GL_ARB_texture_query_lod``.\n"
+ " ``GL_ARB_texture_gather``, ``GL_ARB_texture_cube_map_array`` and "
+ "``GL_ARB_shader_draw_parameters``.\n"
"\n"
" To debug shaders, use the --debug-gpu-shaders command line option"
" to see full GLSL shader compilation and linking errors.\n"
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index 769618005af..44949c478cc 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -62,6 +62,7 @@ set(SRC
bpy_gizmo_wrap.c
bpy_interface.c
bpy_interface_atexit.c
+ bpy_interface_run.c
bpy_intern_string.c
bpy_library_load.c
bpy_library_write.c
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index c311041e4cb..b0b36baa839 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -25,6 +25,7 @@
*/
#include <Python.h>
+#include <frameobject.h>
#include "MEM_guardedalloc.h"
@@ -62,6 +63,8 @@
#endif
#include "BPY_extern.h"
+#include "BPY_extern_python.h"
+#include "BPY_extern_run.h"
#include "../generic/py_capi_utils.h"
@@ -426,180 +429,19 @@ void BPY_python_use_system_env(void)
py_use_system_env = true;
}
-static void python_script_error_jump_text(struct Text *text)
-{
- int lineno;
- int offset;
- python_script_error_jump(text->id.name + 2, &lineno, &offset);
- if (lineno != -1) {
- /* select the line with the error */
- txt_move_to(text, lineno - 1, INT_MAX, false);
- txt_move_to(text, lineno - 1, offset, true);
- }
-}
-
-void BPY_python_backtrace(/* FILE */ void *fp)
+void BPY_python_backtrace(FILE *fp)
{
fputs("\n# Python backtrace\n", fp);
- PyC_StackPrint(fp);
-}
-
-/* super annoying, undo _PyModule_Clear(), bug [#23871] */
-#define PYMODULE_CLEAR_WORKAROUND
-
-#ifdef PYMODULE_CLEAR_WORKAROUND
-/* bad!, we should never do this, but currently only safe way I could find to keep namespace.
- * from being cleared. - campbell */
-typedef struct {
- PyObject_HEAD PyObject *md_dict;
- /* omit other values, we only want the dict. */
-} PyModuleObject;
-#endif
-
-/* returns a dummy filename for a textblock so we can tell what file a text block comes from */
-static void bpy_text_filename_get(char *fn, const Main *bmain, size_t fn_len, const Text *text)
-{
- BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bmain, &text->id), SEP, text->id.name + 2);
-}
-
-static bool python_script_exec(
- bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const bool do_jump)
-{
- Main *bmain_old = CTX_data_main(C);
- PyObject *main_mod = NULL;
- PyObject *py_dict = NULL, *py_result = NULL;
- PyGILState_STATE gilstate;
-
- BLI_assert(fn || text);
-
- if (fn == NULL && text == NULL) {
- return 0;
- }
-
- bpy_context_set(C, &gilstate);
-
- PyC_MainModule_Backup(&main_mod);
-
- if (text) {
- char fn_dummy[FILE_MAXDIR];
- bpy_text_filename_get(fn_dummy, bmain_old, sizeof(fn_dummy), text);
-
- if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */
- char *buf;
- PyObject *fn_dummy_py;
-
- fn_dummy_py = PyC_UnicodeFromByte(fn_dummy);
-
- buf = txt_to_buf(text, NULL);
- text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1);
- MEM_freeN(buf);
-
- Py_DECREF(fn_dummy_py);
-
- if (PyErr_Occurred()) {
- if (do_jump) {
- python_script_error_jump_text(text);
- }
- BPY_text_free_code(text);
- }
- }
-
- if (text->compiled) {
- py_dict = PyC_DefaultNameSpace(fn_dummy);
- py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict);
- }
- }
- else {
- FILE *fp = BLI_fopen(fn, "r");
-
- if (fp) {
- py_dict = PyC_DefaultNameSpace(fn);
-
-#ifdef _WIN32
- /* Previously we used PyRun_File to run directly the code on a FILE
- * object, but as written in the Python/C API Ref Manual, chapter 2,
- * 'FILE structs for different C libraries can be different and
- * incompatible'.
- * So now we load the script file data to a buffer.
- *
- * Note on use of 'globals()', it's important not copy the dictionary because
- * tools may inspect 'sys.modules["__main__"]' for variables defined in the code
- * where using a copy of 'globals()' causes code execution
- * to leave the main namespace untouched. see: T51444
- *
- * This leaves us with the problem of variables being included,
- * currently this is worked around using 'dict.__del__' it's ugly but works.
- */
- {
- const char *pystring =
- "with open(__file__, 'rb') as f:"
- "exec(compile(f.read(), __file__, 'exec'), globals().__delitem__('f') or globals())";
-
- fclose(fp);
-
- py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict);
- }
-#else
- py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict);
- fclose(fp);
-#endif
- }
- else {
- PyErr_Format(
- PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno));
- py_result = NULL;
- }
- }
-
- if (!py_result) {
- if (text) {
- if (do_jump) {
- /* ensure text is valid before use, the script may have freed its self */
- Main *bmain_new = CTX_data_main(C);
- if ((bmain_old == bmain_new) && (BLI_findindex(&bmain_new->texts, text) != -1)) {
- python_script_error_jump_text(text);
- }
- }
- }
- BPy_errors_to_report(reports);
+ PyThreadState *tstate = PyGILState_GetThisThreadState();
+ if (tstate != NULL && tstate->frame != NULL) {
+ PyFrameObject *frame = tstate->frame;
+ do {
+ const int line = PyCode_Addr2Line(frame->f_code, frame->f_lasti);
+ const char *filename = _PyUnicode_AsString(frame->f_code->co_filename);
+ const char *funcname = _PyUnicode_AsString(frame->f_code->co_name);
+ fprintf(fp, " File \"%s\", line %d in %s\n", filename, line, funcname);
+ } while ((frame = frame->f_back));
}
- else {
- Py_DECREF(py_result);
- }
-
- if (py_dict) {
-#ifdef PYMODULE_CLEAR_WORKAROUND
- PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItem(PyImport_GetModuleDict(),
- bpy_intern_str___main__);
- PyObject *dict_back = mmod->md_dict;
- /* freeing the module will clear the namespace,
- * gives problems running classes defined in this namespace being used later. */
- mmod->md_dict = NULL;
- Py_DECREF(dict_back);
-#endif
-
-#undef PYMODULE_CLEAR_WORKAROUND
- }
-
- PyC_MainModule_Restore(main_mod);
-
- bpy_context_clear(C, &gilstate);
-
- return (py_result != NULL);
-}
-
-/* Can run a file or text block */
-bool BPY_execute_filepath(bContext *C, const char *filepath, struct ReportList *reports)
-{
- return python_script_exec(C, filepath, NULL, reports, false);
-}
-
-bool BPY_execute_text(bContext *C,
- struct Text *text,
- struct ReportList *reports,
- const bool do_jump)
-{
- return python_script_exec(C, NULL, text, reports, do_jump);
}
void BPY_DECREF(void *pyob_ptr)
@@ -620,177 +462,6 @@ void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
PyGILState_Release(gilstate);
}
-/**
- * \return success
- */
-bool BPY_execute_string_as_number(bContext *C,
- const char *imports[],
- const char *expr,
- const char *report_prefix,
- double *r_value)
-{
- PyGILState_STATE gilstate;
- bool ok = true;
-
- if (!r_value || !expr) {
- return -1;
- }
-
- if (expr[0] == '\0') {
- *r_value = 0.0;
- return ok;
- }
-
- bpy_context_set(C, &gilstate);
-
- ok = PyC_RunString_AsNumber(imports, expr, "<expr as number>", r_value);
-
- if (ok == false) {
- if (report_prefix != NULL) {
- BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
- }
- else {
- PyErr_Clear();
- }
- }
-
- bpy_context_clear(C, &gilstate);
-
- return ok;
-}
-
-/**
- * \return success
- */
-bool BPY_execute_string_as_string_and_size(bContext *C,
- const char *imports[],
- const char *expr,
- const char *report_prefix,
- char **r_value,
- size_t *r_value_size)
-{
- BLI_assert(r_value && expr);
- PyGILState_STATE gilstate;
- bool ok = true;
-
- if (expr[0] == '\0') {
- *r_value = NULL;
- return ok;
- }
-
- bpy_context_set(C, &gilstate);
-
- ok = PyC_RunString_AsStringAndSize(imports, expr, "<expr as str>", r_value, r_value_size);
-
- if (ok == false) {
- if (report_prefix != NULL) {
- BPy_errors_to_report_ex(CTX_wm_reports(C), false, false, report_prefix);
- }
- else {
- PyErr_Clear();
- }
- }
-
- bpy_context_clear(C, &gilstate);
-
- return ok;
-}
-
-bool BPY_execute_string_as_string(bContext *C,
- const char *imports[],
- const char *expr,
- const char *report_prefix,
- char **r_value)
-{
- size_t value_dummy_size;
- return BPY_execute_string_as_string_and_size(
- C, imports, expr, report_prefix, r_value, &value_dummy_size);
-}
-
-/**
- * Support both int and pointers.
- *
- * \return success
- */
-bool BPY_execute_string_as_intptr(bContext *C,
- const char *imports[],
- const char *expr,
- const char *report_prefix,
- intptr_t *r_value)
-{
- BLI_assert(r_value && expr);
- PyGILState_STATE gilstate;
- bool ok = true;
-
- if (expr[0] == '\0') {
- *r_value = 0;
- return ok;
- }
-
- bpy_context_set(C, &gilstate);
-
- ok = PyC_RunString_AsIntPtr(imports, expr, "<expr as intptr>", r_value);
-
- if (ok == false) {
- if (report_prefix != NULL) {
- BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
- }
- else {
- PyErr_Clear();
- }
- }
-
- bpy_context_clear(C, &gilstate);
-
- return ok;
-}
-
-bool BPY_execute_string_ex(bContext *C, const char *imports[], const char *expr, bool use_eval)
-{
- BLI_assert(expr);
- PyGILState_STATE gilstate;
- PyObject *main_mod = NULL;
- PyObject *py_dict, *retval;
- bool ok = true;
-
- if (expr[0] == '\0') {
- return ok;
- }
-
- bpy_context_set(C, &gilstate);
-
- PyC_MainModule_Backup(&main_mod);
-
- py_dict = PyC_DefaultNameSpace("<blender string>");
-
- if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
- Py_DECREF(py_dict);
- retval = NULL;
- }
- else {
- retval = PyRun_String(expr, use_eval ? Py_eval_input : Py_file_input, py_dict, py_dict);
- }
-
- if (retval == NULL) {
- ok = false;
- BPy_errors_to_report(CTX_wm_reports(C));
- }
- else {
- Py_DECREF(retval);
- }
-
- PyC_MainModule_Restore(main_mod);
-
- bpy_context_clear(C, &gilstate);
-
- return ok;
-}
-
-bool BPY_execute_string(bContext *C, const char *imports[], const char *expr)
-{
- return BPY_execute_string_ex(C, imports, expr, true);
-}
-
void BPY_modules_load_user(bContext *C)
{
PyGILState_STATE gilstate;
@@ -823,7 +494,7 @@ void BPY_modules_load_user(bContext *C)
}
}
else {
- BPY_execute_text(C, text, NULL, false);
+ BPY_run_text(C, text, NULL, false);
/* Check if the script loaded a new file. */
if (bmain != CTX_data_main(C)) {
diff --git a/source/blender/python/intern/bpy_interface_run.c b/source/blender/python/intern/bpy_interface_run.c
new file mode 100644
index 00000000000..a7593ae7d79
--- /dev/null
+++ b/source/blender/python/intern/bpy_interface_run.c
@@ -0,0 +1,422 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup pythonintern
+ */
+
+#include <stdio.h>
+
+#include <Python.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_fileops.h"
+#include "BLI_listbase.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+
+#include "BKE_context.h"
+#include "BKE_main.h"
+#include "BKE_text.h"
+
+#include "DNA_text_types.h"
+
+#include "BPY_extern.h"
+#include "BPY_extern_run.h"
+
+#include "bpy_capi_utils.h"
+#include "bpy_intern_string.h"
+#include "bpy_traceback.h"
+
+#include "../generic/py_capi_utils.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Private Utilities
+ * \{ */
+
+static void python_script_error_jump_text(Text *text)
+{
+ int lineno;
+ int offset;
+ python_script_error_jump(text->id.name + 2, &lineno, &offset);
+ if (lineno != -1) {
+ /* select the line with the error */
+ txt_move_to(text, lineno - 1, INT_MAX, false);
+ txt_move_to(text, lineno - 1, offset, true);
+ }
+}
+
+/* returns a dummy filename for a textblock so we can tell what file a text block comes from */
+static void bpy_text_filename_get(char *fn, const Main *bmain, size_t fn_len, const Text *text)
+{
+ BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bmain, &text->id), SEP, text->id.name + 2);
+}
+
+/* Very annoying! Undo #_PyModule_Clear(), see T23871. */
+#define PYMODULE_CLEAR_WORKAROUND
+
+#ifdef PYMODULE_CLEAR_WORKAROUND
+/* bad!, we should never do this, but currently only safe way I could find to keep namespace.
+ * from being cleared. - campbell */
+typedef struct {
+ PyObject_HEAD PyObject *md_dict;
+ /* omit other values, we only want the dict. */
+} PyModuleObject;
+#endif
+
+static bool python_script_exec(
+ bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const bool do_jump)
+{
+ Main *bmain_old = CTX_data_main(C);
+ PyObject *main_mod = NULL;
+ PyObject *py_dict = NULL, *py_result = NULL;
+ PyGILState_STATE gilstate;
+
+ BLI_assert(fn || text);
+
+ if (fn == NULL && text == NULL) {
+ return 0;
+ }
+
+ bpy_context_set(C, &gilstate);
+
+ PyC_MainModule_Backup(&main_mod);
+
+ if (text) {
+ char fn_dummy[FILE_MAXDIR];
+ bpy_text_filename_get(fn_dummy, bmain_old, sizeof(fn_dummy), text);
+
+ if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */
+ char *buf;
+ PyObject *fn_dummy_py;
+
+ fn_dummy_py = PyC_UnicodeFromByte(fn_dummy);
+
+ buf = txt_to_buf(text, NULL);
+ text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1);
+ MEM_freeN(buf);
+
+ Py_DECREF(fn_dummy_py);
+
+ if (PyErr_Occurred()) {
+ if (do_jump) {
+ python_script_error_jump_text(text);
+ }
+ BPY_text_free_code(text);
+ }
+ }
+
+ if (text->compiled) {
+ py_dict = PyC_DefaultNameSpace(fn_dummy);
+ py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict);
+ }
+ }
+ else {
+ FILE *fp = BLI_fopen(fn, "r");
+
+ if (fp) {
+ py_dict = PyC_DefaultNameSpace(fn);
+
+#ifdef _WIN32
+ /* Previously we used PyRun_File to run directly the code on a FILE
+ * object, but as written in the Python/C API Ref Manual, chapter 2,
+ * 'FILE structs for different C libraries can be different and
+ * incompatible'.
+ * So now we load the script file data to a buffer.
+ *
+ * Note on use of 'globals()', it's important not copy the dictionary because
+ * tools may inspect 'sys.modules["__main__"]' for variables defined in the code
+ * where using a copy of 'globals()' causes code execution
+ * to leave the main namespace untouched. see: T51444
+ *
+ * This leaves us with the problem of variables being included,
+ * currently this is worked around using 'dict.__del__' it's ugly but works.
+ */
+ {
+ const char *pystring =
+ "with open(__file__, 'rb') as f:"
+ "exec(compile(f.read(), __file__, 'exec'), globals().__delitem__('f') or globals())";
+
+ fclose(fp);
+
+ py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict);
+ }
+#else
+ py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict);
+ fclose(fp);
+#endif
+ }
+ else {
+ PyErr_Format(
+ PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno));
+ py_result = NULL;
+ }
+ }
+
+ if (!py_result) {
+ if (text) {
+ if (do_jump) {
+ /* ensure text is valid before use, the script may have freed its self */
+ Main *bmain_new = CTX_data_main(C);
+ if ((bmain_old == bmain_new) && (BLI_findindex(&bmain_new->texts, text) != -1)) {
+ python_script_error_jump_text(text);
+ }
+ }
+ }
+ BPy_errors_to_report(reports);
+ }
+ else {
+ Py_DECREF(py_result);
+ }
+
+ if (py_dict) {
+#ifdef PYMODULE_CLEAR_WORKAROUND
+ PyModuleObject *mmod = (PyModuleObject *)PyDict_GetItem(PyImport_GetModuleDict(),
+ bpy_intern_str___main__);
+ PyObject *dict_back = mmod->md_dict;
+ /* freeing the module will clear the namespace,
+ * gives problems running classes defined in this namespace being used later. */
+ mmod->md_dict = NULL;
+ Py_DECREF(dict_back);
+#endif
+
+#undef PYMODULE_CLEAR_WORKAROUND
+ }
+
+ PyC_MainModule_Restore(main_mod);
+
+ bpy_context_clear(C, &gilstate);
+
+ return (py_result != NULL);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Run Text / Filename / String
+ * \{ */
+
+/* Can run a file or text block */
+bool BPY_run_filepath(bContext *C, const char *filepath, struct ReportList *reports)
+{
+ return python_script_exec(C, filepath, NULL, reports, false);
+}
+
+bool BPY_run_text(bContext *C, struct Text *text, struct ReportList *reports, const bool do_jump)
+{
+ return python_script_exec(C, NULL, text, reports, do_jump);
+}
+
+/**
+ * \param mode: Passed to #PyRun_String, matches Python's `compile` functions mode argument.
+ * #Py_eval_input for `eval`, #Py_file_input for `exec`.
+ */
+static bool bpy_run_string_impl(bContext *C,
+ const char *imports[],
+ const char *expr,
+ const int mode)
+{
+ BLI_assert(expr);
+ PyGILState_STATE gilstate;
+ PyObject *main_mod = NULL;
+ PyObject *py_dict, *retval;
+ bool ok = true;
+
+ if (expr[0] == '\0') {
+ return ok;
+ }
+
+ bpy_context_set(C, &gilstate);
+
+ PyC_MainModule_Backup(&main_mod);
+
+ py_dict = PyC_DefaultNameSpace("<blender string>");
+
+ if (imports && (!PyC_NameSpace_ImportArray(py_dict, imports))) {
+ Py_DECREF(py_dict);
+ retval = NULL;
+ }
+ else {
+ retval = PyRun_String(expr, mode, py_dict, py_dict);
+ }
+
+ if (retval == NULL) {
+ ok = false;
+ BPy_errors_to_report(CTX_wm_reports(C));
+ }
+ else {
+ Py_DECREF(retval);
+ }
+
+ PyC_MainModule_Restore(main_mod);
+
+ bpy_context_clear(C, &gilstate);
+
+ return ok;
+}
+
+/**
+ * Run an expression, matches: `exec(compile(..., "eval"))`
+ */
+bool BPY_run_string_eval(bContext *C, const char *imports[], const char *expr)
+{
+ return bpy_run_string_impl(C, imports, expr, Py_eval_input);
+}
+
+/**
+ * Run an entire script, matches: `exec(compile(..., "exec"))`
+ */
+bool BPY_run_string_exec(bContext *C, const char *imports[], const char *expr)
+{
+ return bpy_run_string_impl(C, imports, expr, Py_file_input);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Run Python & Evaluate Utilities
+ *
+ * Return values as plain C types, useful to run Python scripts
+ * in code that doesn't deal with Python data-types.
+ * \{ */
+
+/**
+ * \return success
+ */
+bool BPY_run_string_as_number(bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ double *r_value)
+{
+ PyGILState_STATE gilstate;
+ bool ok = true;
+
+ if (!r_value || !expr) {
+ return -1;
+ }
+
+ if (expr[0] == '\0') {
+ *r_value = 0.0;
+ return ok;
+ }
+
+ bpy_context_set(C, &gilstate);
+
+ ok = PyC_RunString_AsNumber(imports, expr, "<expr as number>", r_value);
+
+ if (ok == false) {
+ if (report_prefix != NULL) {
+ BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
+ }
+ else {
+ PyErr_Clear();
+ }
+ }
+
+ bpy_context_clear(C, &gilstate);
+
+ return ok;
+}
+
+/**
+ * \return success
+ */
+bool BPY_run_string_as_string_and_size(bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ char **r_value,
+ size_t *r_value_size)
+{
+ BLI_assert(r_value && expr);
+ PyGILState_STATE gilstate;
+ bool ok = true;
+
+ if (expr[0] == '\0') {
+ *r_value = NULL;
+ return ok;
+ }
+
+ bpy_context_set(C, &gilstate);
+
+ ok = PyC_RunString_AsStringAndSize(imports, expr, "<expr as str>", r_value, r_value_size);
+
+ if (ok == false) {
+ if (report_prefix != NULL) {
+ BPy_errors_to_report_ex(CTX_wm_reports(C), false, false, report_prefix);
+ }
+ else {
+ PyErr_Clear();
+ }
+ }
+
+ bpy_context_clear(C, &gilstate);
+
+ return ok;
+}
+
+bool BPY_run_string_as_string(bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ char **r_value)
+{
+ size_t value_dummy_size;
+ return BPY_run_string_as_string_and_size(
+ C, imports, expr, report_prefix, r_value, &value_dummy_size);
+}
+
+/**
+ * Support both int and pointers.
+ *
+ * \return success
+ */
+bool BPY_run_string_as_intptr(bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ intptr_t *r_value)
+{
+ BLI_assert(r_value && expr);
+ PyGILState_STATE gilstate;
+ bool ok = true;
+
+ if (expr[0] == '\0') {
+ *r_value = 0;
+ return ok;
+ }
+
+ bpy_context_set(C, &gilstate);
+
+ ok = PyC_RunString_AsIntPtr(imports, expr, "<expr as intptr>", r_value);
+
+ if (ok == false) {
+ if (report_prefix != NULL) {
+ BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
+ }
+ else {
+ PyErr_Clear();
+ }
+ }
+
+ bpy_context_clear(C, &gilstate);
+
+ return ok;
+}
+
+/** \} */
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
index 9d76f07e4fb..16ea05771d0 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.c
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -1053,7 +1053,7 @@ static Mesh *bvh_get_mesh(const char *funcname,
}
*r_free_mesh = true;
- return mesh_create_eval_final_render(depsgraph, scene, ob, &data_masks);
+ return mesh_create_eval_final(depsgraph, scene, ob, &data_masks);
}
if (ob_eval != NULL) {
if (use_cage) {
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 0790d40d56c..440c54f5eeb 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -519,9 +519,8 @@ float RE_engine_get_camera_shift_x(RenderEngine *engine, Object *camera, bool us
if (use_spherical_stereo || re == NULL) {
return BKE_camera_multiview_shift_x(NULL, camera, NULL);
}
- else {
- return BKE_camera_multiview_shift_x(&re->r, camera, re->viewname);
- }
+
+ return BKE_camera_multiview_shift_x(&re->r, camera, re->viewname);
}
void RE_engine_get_camera_model_matrix(RenderEngine *engine,
@@ -610,13 +609,13 @@ static void engine_depsgraph_init(RenderEngine *engine, ViewLayer *view_layer)
if (engine->re->r.scemode & R_BUTS_PREVIEW) {
Depsgraph *depsgraph = engine->depsgraph;
- DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
- DEG_evaluate_on_framechange(bmain, depsgraph, CFRA);
+ DEG_graph_relations_update(depsgraph);
+ DEG_evaluate_on_framechange(depsgraph, CFRA);
DEG_ids_check_recalc(bmain, depsgraph, scene, view_layer, true);
DEG_ids_clear_recalc(bmain, depsgraph);
}
else {
- BKE_scene_graph_update_for_newframe(engine->depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(engine->depsgraph);
}
}
@@ -638,7 +637,7 @@ void RE_engine_frame_set(RenderEngine *engine, int frame, float subframe)
CLAMP(cfra, MINAFRAME, MAXFRAME);
BKE_scene_frame_set(re->scene, cfra);
- BKE_scene_graph_update_for_newframe(engine->depsgraph, re->main);
+ BKE_scene_graph_update_for_newframe(engine->depsgraph);
BKE_scene_camera_switch_update(re->scene);
}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 3236026c69f..86c9c64098b 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -1964,7 +1964,7 @@ void RE_SetReports(Render *re, ReportList *reports)
static void render_update_depsgraph(Render *re)
{
Scene *scene = re->scene;
- DEG_evaluate_on_framechange(re->main, re->pipeline_depsgraph, CFRA);
+ DEG_evaluate_on_framechange(re->pipeline_depsgraph, CFRA);
BKE_scene_update_sound(re->pipeline_depsgraph, re->main);
}
@@ -1977,7 +1977,7 @@ static void render_init_depsgraph(Render *re)
DEG_debug_name_set(re->pipeline_depsgraph, "RENDER PIPELINE");
/* Make sure there is a correct evaluated scene pointer. */
- DEG_graph_build_for_render_pipeline(re->pipeline_depsgraph, re->main, scene, view_layer);
+ DEG_graph_build_for_render_pipeline(re->pipeline_depsgraph);
/* Update immediately so we have proper evaluated scene. */
render_update_depsgraph(re);
diff --git a/source/blender/simulation/CMakeLists.txt b/source/blender/simulation/CMakeLists.txt
index cbc6ee65303..e47586d55cc 100644
--- a/source/blender/simulation/CMakeLists.txt
+++ b/source/blender/simulation/CMakeLists.txt
@@ -45,8 +45,8 @@ set(SRC
intern/particle_function.cc
intern/particle_mesh_emitter.cc
intern/simulation_collect_influences.cc
- intern/simulation_solver_influences.cc
intern/simulation_solver.cc
+ intern/simulation_solver_influences.cc
intern/simulation_update.cc
intern/ConstrainedConjugateGradient.h
@@ -56,8 +56,8 @@ set(SRC
intern/particle_function.hh
intern/particle_mesh_emitter.hh
intern/simulation_collect_influences.hh
- intern/simulation_solver_influences.hh
intern/simulation_solver.hh
+ intern/simulation_solver_influences.hh
intern/time_interval.hh
SIM_mass_spring.h
diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_types.h b/source/blender/windowmanager/gizmo/WM_gizmo_types.h
index bddf54b846f..8e2b5e04e42 100644
--- a/source/blender/windowmanager/gizmo/WM_gizmo_types.h
+++ b/source/blender/windowmanager/gizmo/WM_gizmo_types.h
@@ -244,7 +244,7 @@ struct wmGizmo {
int drag_part;
/** Distance to bias this gizmo above others when picking
- * (in worldspace, scaled by the gizmo scale - when used). */
+ * (in world-space, scaled by the gizmo scale - when used). */
float select_bias;
/**
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 43c08a2b980..5d0520bb674 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -66,6 +66,7 @@
#ifdef WITH_PYTHON
# include "BPY_extern.h"
+# include "BPY_extern_run.h"
#endif
/* ****************************************************** */
@@ -270,7 +271,7 @@ void WM_keyconfig_reload(bContext *C)
{
if (CTX_py_init_get(C) && !G.background) {
#ifdef WITH_PYTHON
- BPY_execute_string(C, (const char *[]){"bpy", NULL}, "bpy.utils.keyconfig_init()");
+ BPY_run_string_eval(C, (const char *[]){"bpy", NULL}, "bpy.utils.keyconfig_init()");
#endif
}
}
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index ec18a401fa4..37ed9f89bc7 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -401,7 +401,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
}
/* XXX todo, multiline drag draws... but maybe not, more types mixed wont work well */
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
for (drag = wm->drags.first; drag; drag = drag->next) {
const uchar text_col[] = {255, 255, 255, 255};
int iconsize = UI_DPI_ICON_SIZE;
@@ -495,5 +495,5 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
}
}
}
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index b8cb5432a49..6f3fbf77987 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -307,7 +307,9 @@ static void wm_region_test_xr_do_draw(const wmWindowManager *wm,
static bool wm_region_use_viewport_by_type(short space_type, short region_type)
{
- return (ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE) && region_type == RGN_TYPE_WINDOW);
+ return (ELEM(space_type, SPACE_VIEW3D, SPACE_IMAGE, SPACE_NODE) &&
+ region_type == RGN_TYPE_WINDOW) ||
+ ((space_type == SPACE_SEQ) && region_type == RGN_TYPE_PREVIEW);
}
bool WM_region_use_viewport(ScrArea *area, ARegion *region)
@@ -574,9 +576,8 @@ void wm_draw_region_blend(ARegion *region, int view, bool blend)
const float rectg[4] = {rect_geo.xmin, rect_geo.ymin, rect_geo.xmax, rect_geo.ymax};
if (blend) {
- /* GL_ONE because regions drawn offscreen have premultiplied alpha. */
- GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ /* Regions drawn offscreen have premultiplied alpha. */
+ GPU_blend(GPU_BLEND_ALPHA_PREMULT);
}
/* setup actual texture */
@@ -601,8 +602,7 @@ void wm_draw_region_blend(ARegion *region, int view, bool blend)
GPU_texture_unbind(texture);
if (blend) {
- GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
}
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index bea4faa779a..c363fdcc9d4 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -352,7 +352,7 @@ void wm_event_do_depsgraph(bContext *C, bool is_after_open_file)
*/
Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true);
if (is_after_open_file) {
- DEG_graph_relations_update(depsgraph, bmain, scene, view_layer);
+ DEG_graph_relations_update(depsgraph);
DEG_graph_on_visible_update(bmain, depsgraph, true);
}
DEG_make_active(depsgraph);
@@ -1363,8 +1363,7 @@ static int wm_operator_invoke(bContext *C,
ScrArea *area = CTX_wm_area(C);
/* Wrap only in X for header. */
- if (region &&
- ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER, RGN_TYPE_FOOTER)) {
+ if (region && RGN_TYPE_IS_HEADER_ANY(region->regiontype)) {
wrap = WM_CURSOR_WRAP_X;
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index ef4f2b4a62a..62d9c099cd5 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -121,7 +121,8 @@
#include "RE_engine.h"
#ifdef WITH_PYTHON
-# include "BPY_extern.h"
+# include "BPY_extern_python.h"
+# include "BPY_extern_run.h"
#endif
#include "DEG_depsgraph.h"
@@ -579,14 +580,14 @@ static void wm_file_read_post(bContext *C,
if (use_userdef || reset_app_template) {
/* Only run when we have a template path found. */
if (BKE_appdir_app_template_any()) {
- BPY_execute_string(
+ BPY_run_string_eval(
C, (const char *[]){"bl_app_template_utils", NULL}, "bl_app_template_utils.reset()");
reset_all = true;
}
}
if (reset_all) {
/* sync addons, these may have changed from the defaults */
- BPY_execute_string(C, (const char *[]){"addon_utils", NULL}, "addon_utils.reset_all()");
+ BPY_run_string_eval(C, (const char *[]){"addon_utils", NULL}, "addon_utils.reset_all()");
}
if (use_data) {
BPY_python_reset(C);
@@ -923,7 +924,7 @@ void wm_homefile_read(bContext *C,
*
* Note that this fits into 'wm_file_read_pre' function but gets messy
* since we need to know if 'reset_app_template' is true. */
- BPY_execute_string(C, (const char *[]){"addon_utils", NULL}, "addon_utils.disable_all()");
+ BPY_run_string_eval(C, (const char *[]){"addon_utils", NULL}, "addon_utils.disable_all()");
}
#endif /* WITH_PYTHON */
}
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 55233168ab2..67733ffc673 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -236,7 +236,7 @@ static void wm_gesture_draw_rect(wmGesture *gt)
uint shdr_pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.05f);
@@ -245,7 +245,7 @@ static void wm_gesture_draw_rect(wmGesture *gt)
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -274,7 +274,7 @@ static void wm_gesture_draw_circle(wmGesture *gt)
{
rcti *rect = (rcti *)gt->customdata;
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
const uint shdr_pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
@@ -286,7 +286,7 @@ static void wm_gesture_draw_circle(wmGesture *gt)
immUnbindProgram();
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -353,9 +353,7 @@ static void draw_filled_lasso(wmGesture *gt)
draw_filled_lasso_px_cb,
&lasso_fill_data);
- /* Additive Blending */
- GPU_blend(true);
- GPU_blend_set_func(GPU_ONE, GPU_ONE);
+ GPU_blend(GPU_BLEND_ADDITIVE);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
GPU_shader_bind(state.shader);
@@ -369,8 +367,7 @@ static void draw_filled_lasso(wmGesture *gt)
MEM_freeN(pixel_buf);
- GPU_blend(false);
- GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_NONE);
}
MEM_freeN(mcoords);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 03e84f098c0..e8f663b0c4a 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -85,6 +85,7 @@
#ifdef WITH_PYTHON
# include "BPY_extern.h"
+# include "BPY_extern_python.h"
#endif
#include "GHOST_C-api.h"
@@ -349,8 +350,6 @@ void WM_init(bContext *C, int argc, const char **argv)
BKE_material_copybuf_clear();
ED_render_clear_mtex_copybuf();
- // GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
wm_history_file_read();
/* allow a path of "", this is what happens when making a new file */
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 1964813fff9..9b25d660ff6 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2393,7 +2393,7 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void
}
GPU_matrix_translate_2f((float)x, (float)y);
- GPU_blend(true);
+ GPU_blend(GPU_BLEND_ALPHA);
GPU_line_smooth(true);
/* apply zoom if available */
@@ -2472,7 +2472,7 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void
BLF_position(fontid, -0.5f * strwidth, -0.5f * strheight, 0.0f);
BLF_draw(fontid, str, strdrawlen);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
GPU_line_smooth(false);
}
@@ -3151,7 +3151,6 @@ static const EnumPropertyItem redraw_timer_type_items[] = {
};
static void redraw_timer_step(bContext *C,
- Main *bmain,
Scene *scene,
struct Depsgraph *depsgraph,
wmWindow *win,
@@ -3202,7 +3201,7 @@ static void redraw_timer_step(bContext *C,
}
else if (type == eRTAnimationStep) {
scene->r.cfra += (cfra == scene->r.cfra) ? 1 : -1;
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
}
else if (type == eRTAnimationPlay) {
/* play anim, return on same frame as started with */
@@ -3215,7 +3214,7 @@ static void redraw_timer_step(bContext *C,
scene->r.cfra = scene->r.sfra;
}
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ BKE_scene_graph_update_for_newframe(depsgraph);
redraw_timer_window_swap(C);
}
}
@@ -3231,7 +3230,6 @@ static void redraw_timer_step(bContext *C,
static int redraw_timer_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
wmWindow *win = CTX_wm_window(C);
ScrArea *area = CTX_wm_area(C);
@@ -3256,7 +3254,7 @@ static int redraw_timer_exec(bContext *C, wmOperator *op)
wm_window_make_drawable(wm, win);
for (a = 0; a < iter; a++) {
- redraw_timer_step(C, bmain, scene, depsgraph, win, area, region, type, cfra);
+ redraw_timer_step(C, scene, depsgraph, win, area, region, type, cfra);
iter_steps += 1;
if (time_limit != 0.0) {
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index a0a21fadbbb..9d472ed4597 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -315,9 +315,7 @@ static void playanim_toscreen(
/* checkerboard for case alpha */
if (ibuf->planes == 32) {
- GPU_blend(true);
- GPU_blend_set_func_separate(
- GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(GPU_BLEND_ALPHA);
imm_draw_box_checker_2d_ex(offs_x,
offs_y,
@@ -342,7 +340,7 @@ static void playanim_toscreen(
((ps->draw_flip[1] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_y),
NULL);
- GPU_blend(false);
+ GPU_blend(GPU_BLEND_NONE);
pupdate_time();
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index a8a1817be5e..ac00fc36a89 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -658,9 +658,6 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm,
wm_window_swap_buffers(win);
// GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified);
-
- /* standard state vars for window */
- GPU_state_init();
}
else {
wm_window_set_drawable(wm, prev_windrawable, false);
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index b8e99899821..164e670c444 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -61,7 +61,8 @@
# endif
# ifdef WITH_PYTHON
-# include "BPY_extern.h"
+# include "BPY_extern_python.h"
+# include "BPY_extern_run.h"
# endif
# include "RE_engine.h"
@@ -1779,7 +1780,7 @@ static int arg_handle_python_file_run(int argc, const char **argv, void *data)
BLI_path_abs_from_cwd(filename, sizeof(filename));
bool ok;
- BPY_CTX_SETUP(ok = BPY_execute_filepath(C, filename, NULL));
+ BPY_CTX_SETUP(ok = BPY_run_filepath(C, filename, NULL));
if (!ok && app_state.exit_code_on_error.python) {
printf("\nError: script failed, file: '%s', exiting.\n", argv[1]);
BPY_python_end();
@@ -1814,7 +1815,7 @@ static int arg_handle_python_text_run(int argc, const char **argv, void *data)
bool ok;
if (text) {
- BPY_CTX_SETUP(ok = BPY_execute_text(C, text, NULL, false));
+ BPY_CTX_SETUP(ok = BPY_run_text(C, text, NULL, false));
}
else {
printf("\nError: text block not found %s.\n", argv[1]);
@@ -1851,7 +1852,7 @@ static int arg_handle_python_expr_run(int argc, const char **argv, void *data)
/* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
if (argc > 1) {
bool ok;
- BPY_CTX_SETUP(ok = BPY_execute_string_ex(C, NULL, argv[1], false));
+ BPY_CTX_SETUP(ok = BPY_run_string_exec(C, NULL, argv[1]));
if (!ok && app_state.exit_code_on_error.python) {
printf("\nError: script failed, expr: '%s', exiting.\n", argv[1]);
BPY_python_end();
@@ -1878,7 +1879,7 @@ static int arg_handle_python_console_run(int UNUSED(argc), const char **argv, vo
# ifdef WITH_PYTHON
bContext *C = data;
- BPY_CTX_SETUP(BPY_execute_string(C, (const char *[]){"code", NULL}, "code.interact()"));
+ BPY_CTX_SETUP(BPY_run_string_eval(C, (const char *[]){"code", NULL}, "code.interact()"));
return 0;
# else
@@ -1951,7 +1952,7 @@ static int arg_handle_addons_set(int argc, const char **argv, void *data)
BLI_snprintf(str, slen, script_str, argv[1]);
BLI_assert(strlen(str) + 1 == slen);
- BPY_CTX_SETUP(BPY_execute_string_ex(C, NULL, str, false));
+ BPY_CTX_SETUP(BPY_run_string_exec(C, NULL, str));
free(str);
# else
UNUSED_VARS(argv, data);
diff --git a/source/creator/creator_signals.c b/source/creator/creator_signals.c
index ad0b7b2547d..29e12a96fe1 100644
--- a/source/creator/creator_signals.c
+++ b/source/creator/creator_signals.c
@@ -60,7 +60,7 @@
# include <signal.h>
# ifdef WITH_PYTHON
-# include "BPY_extern.h" /* BPY_python_backtrace */
+# include "BPY_extern_python.h" /* BPY_python_backtrace */
# endif
# include "creator_intern.h" /* own include */