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
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2020-09-13 01:43:21 +0300
committerHans Goudey <h.goudey@me.com>2020-09-13 01:43:21 +0300
commit1496526dce5628948350aff87aacea5938b99976 (patch)
treeb9fc80058dfc220c5863de8e67a9be4b0deeaab3
parent6ebc8278dee691cde48b6d3b0fd7aa52c6c379d7 (diff)
parent3eaca737531a917e60350bd74d52849b612831da (diff)
Merge branch 'property-search-start-end-operators' into property-search-highlight-tabs
-rw-r--r--CMakeLists.txt8
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.h2
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h2
-rw-r--r--intern/memutil/MEM_RefCounted.h2
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc10
-rw-r--r--release/datafiles/userdef/userdef_default_theme.c1
-rw-r--r--release/scripts/modules/bpy_types.py17
-rw-r--r--release/scripts/startup/bl_ui/space_image.py3
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py1
-rw-r--r--source/blender/blenfont/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/BKE_customdata.h6
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h3
-rw-r--r--source/blender/blenkernel/BKE_node.h16
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/cachefile.c38
-rw-r--r--source/blender/blenkernel/intern/constraint.c3
-rw-r--r--source/blender/blenkernel/intern/gpencil.c164
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.c15
-rw-r--r--source/blender/blenkernel/intern/hair.c77
-rw-r--r--source/blender/blenkernel/intern/image_gpu.c12
-rw-r--r--source/blender/blenkernel/intern/pointcloud.c72
-rw-r--r--source/blender/blenkernel/intern/simulation.cc98
-rw-r--r--source/blender/blenkernel/intern/softbody.c2
-rw-r--r--source/blender/blenkernel/intern/sound.c71
-rw-r--r--source/blender/blenkernel/intern/texture.c70
-rw-r--r--source/blender/blenkernel/intern/volume.cc65
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c2
-rw-r--r--source/blender/blenlib/intern/math_bits_inline.c2
-rw-r--r--source/blender/blenlib/intern/math_matrix.c6
-rw-r--r--source/blender/blenlib/intern/path_util.c2
-rw-r--r--source/blender/blenloader/BLO_read_write.h2
-rw-r--r--source/blender/blenloader/intern/readfile.c449
-rw-r--r--source/blender/blenloader/intern/versioning_userdef.c2
-rw-r--r--source/blender/blenloader/intern/writefile.c288
-rw-r--r--source/blender/bmesh/bmesh.h2
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.cpp6
-rw-r--r--source/blender/compositor/intern/COM_NodeGraph.cpp2
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.cpp14
-rw-r--r--source/blender/compositor/nodes/COM_ImageNode.cpp2
-rw-r--r--source/blender/compositor/operations/COM_ReadBufferOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.cpp2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_physics.cc2
-rw-r--r--source/blender/draw/CMakeLists.txt21
-rw-r--r--source/blender/draw/DRW_engine.h4
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h4
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c26
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl4
-rw-r--r--source/blender/draw/engines/image/image_engine.c304
-rw-r--r--source/blender/draw/engines/image/image_engine.h (renamed from source/blender/gpu/GPU_debug.h)16
-rw-r--r--source/blender/draw/engines/image/image_private.h69
-rw-r--r--source/blender/draw/engines/image/image_shader.c77
-rw-r--r--source/blender/draw/engines/image/shaders/engine_image_frag.glsl91
-rw-r--r--source/blender/draw/engines/image/shaders/engine_image_vert.glsl31
-rw-r--r--source/blender/draw/engines/overlay/overlay_background.c7
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_uv.c394
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.c47
-rw-r--r--source/blender/draw/engines/overlay/overlay_grid.c53
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.h60
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader.c149
-rw-r--r--source/blender/draw/engines/overlay/shaders/background_frag.glsl7
-rw-r--r--source/blender/draw/engines/overlay/shaders/common_overlay_lib.glsl5
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_edges_frag.glsl77
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_edges_geom.glsl63
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_edges_vert.glsl32
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_face_dots_vert.glsl18
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_faces_vert.glsl22
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_stretching_vert.glsl98
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_tiled_image_borders_vert.glsl12
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_verts_frag.glsl33
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_verts_vert.glsl44
-rw-r--r--source/blender/draw/engines/overlay/shaders/grid_vert.glsl7
-rw-r--r--source/blender/draw/intern/DRW_render.h11
-rw-r--r--source/blender/draw/intern/draw_common.c5
-rw-r--r--source/blender/draw/intern/draw_common.h4
-rw-r--r--source/blender/draw/intern/draw_fluid.c8
-rw-r--r--source/blender/draw/intern/draw_hair.c8
-rw-r--r--source/blender/draw/intern/draw_manager.c319
-rw-r--r--source/blender/draw/intern/draw_manager.h2
-rw-r--r--source/blender/draw/intern/draw_manager_data.c16
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c6
-rw-r--r--source/blender/draw/intern/draw_manager_profiling.c28
-rw-r--r--source/blender/draw/intern/draw_manager_text.c130
-rw-r--r--source/blender/draw/intern/draw_view.c60
-rw-r--r--source/blender/draw/intern/draw_view.h1
-rw-r--r--source/blender/draw/intern/shaders/common_globals_lib.glsl2
-rw-r--r--source/blender/draw/tests/shaders_test.cc20
-rw-r--r--source/blender/editors/animation/CMakeLists.txt4
-rw-r--r--source/blender/editors/armature/CMakeLists.txt5
-rw-r--r--source/blender/editors/curve/CMakeLists.txt5
-rw-r--r--source/blender/editors/curve/editcurve.c9
-rw-r--r--source/blender/editors/curve/editcurve_add.c7
-rw-r--r--source/blender/editors/gizmo_library/CMakeLists.txt5
-rw-r--r--source/blender/editors/gpencil/CMakeLists.txt5
-rw-r--r--source/blender/editors/include/ED_fileselect.h1
-rw-r--r--source/blender/editors/include/UI_interface.h5
-rw-r--r--source/blender/editors/interface/CMakeLists.txt5
-rw-r--r--source/blender/editors/interface/interface.c2
-rw-r--r--source/blender/editors/interface/interface_icons.c4
-rw-r--r--source/blender/editors/interface/interface_intern.h8
-rw-r--r--source/blender/editors/interface/interface_layout.c313
-rw-r--r--source/blender/editors/interface/interface_templates.c2
-rw-r--r--source/blender/editors/mask/CMakeLists.txt5
-rw-r--r--source/blender/editors/mesh/CMakeLists.txt5
-rw-r--r--source/blender/editors/mesh/editmesh_add.c2
-rw-r--r--source/blender/editors/object/CMakeLists.txt5
-rw-r--r--source/blender/editors/object/object_add.c32
-rw-r--r--source/blender/editors/object/object_constraint.c12
-rw-r--r--source/blender/editors/object/object_edit.c31
-rw-r--r--source/blender/editors/physics/CMakeLists.txt5
-rw-r--r--source/blender/editors/render/CMakeLists.txt5
-rw-r--r--source/blender/editors/render/render_internal.c1
-rw-r--r--source/blender/editors/screen/CMakeLists.txt5
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt5
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c20
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_dyntopo.c28
-rw-r--r--source/blender/editors/space_action/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_api/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_api/spacetypes.c8
-rw-r--r--source/blender/editors/space_buttons/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_clip/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_console/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_file/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_file/file_intern.h7
-rw-r--r--source/blender/editors/space_file/file_ops.c39
-rw-r--r--source/blender/editors/space_file/filesel.c29
-rw-r--r--source/blender/editors/space_graph/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c16
-rw-r--r--source/blender/editors/space_image/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_image/image_draw.c37
-rw-r--r--source/blender/editors/space_image/image_intern.h1
-rw-r--r--source/blender/editors/space_image/space_image.c77
-rw-r--r--source/blender/editors/space_info/CMakeLists.txt5
-rw-r--r--source/blender/editors/space_nla/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_node/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_outliner/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_script/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_sequencer/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_statusbar/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_text/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_topbar/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c2
-rw-r--r--source/blender/editors/transform/CMakeLists.txt4
-rw-r--r--source/blender/editors/transform/transform_constraints.c51
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c3
-rw-r--r--source/blender/editors/transform/transform_mode_edge_seq_slide.c27
-rw-r--r--source/blender/editors/transform/transform_mode_translate.c61
-rw-r--r--source/blender/editors/transform/transform_snap.c87
-rw-r--r--source/blender/editors/util/CMakeLists.txt4
-rw-r--r--source/blender/editors/uvedit/CMakeLists.txt4
-rw-r--r--source/blender/gpencil_modifiers/CMakeLists.txt1
-rw-r--r--source/blender/gpu/CMakeLists.txt3
-rw-r--r--source/blender/gpu/GPU_capabilities.h2
-rw-r--r--source/blender/gpu/GPU_common.h4
-rw-r--r--source/blender/gpu/GPU_state.h12
-rw-r--r--source/blender/gpu/GPU_texture.h5
-rw-r--r--source/blender/gpu/GPU_vertex_buffer.h3
-rw-r--r--source/blender/gpu/intern/gpu_capabilities.cc5
-rw-r--r--source/blender/gpu/intern/gpu_capabilities_private.hh3
-rw-r--r--source/blender/gpu/intern/gpu_context_private.hh2
-rw-r--r--source/blender/gpu/intern/gpu_debug.cc44
-rw-r--r--source/blender/gpu/intern/gpu_immediate.cc2
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c1
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.hh1
-rw-r--r--source/blender/gpu/intern/gpu_state.cc46
-rw-r--r--source/blender/gpu/intern/gpu_state_private.hh16
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc21
-rw-r--r--source/blender/gpu/intern/gpu_vertex_buffer.cc7
-rw-r--r--source/blender/gpu/intern/gpu_vertex_buffer_private.hh2
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc2
-rw-r--r--source/blender/gpu/opengl/gl_backend.cc15
-rw-r--r--source/blender/gpu/opengl/gl_context.hh2
-rw-r--r--source/blender/gpu/opengl/gl_debug.cc22
-rw-r--r--source/blender/gpu/opengl/gl_drawlist.hh1
-rw-r--r--source/blender/gpu/opengl/gl_shader_interface.cc37
-rw-r--r--source/blender/gpu/opengl/gl_state.cc108
-rw-r--r--source/blender/gpu/opengl/gl_state.hh27
-rw-r--r--source/blender/gpu/opengl/gl_vertex_buffer.cc5
-rw-r--r--source/blender/gpu/opengl/gl_vertex_buffer.hh2
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c4
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.cpp32
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.h18
-rw-r--r--source/blender/imbuf/intern/dds/Color.h4
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.cpp34
-rw-r--r--source/blender/imbuf/intern/dds/ColorBlock.h12
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.h6
-rw-r--r--source/blender/imbuf/intern/dds/Image.h2
-rw-r--r--source/blender/makesdna/DNA_image_defaults.h2
-rw-r--r--source/blender/makesdna/DNA_image_types.h6
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h3
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt5
-rw-r--r--source/blender/makesrna/intern/rna_particle.c128
-rw-r--r--source/blender/makesrna/intern/rna_space.c5
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c10
-rw-r--r--source/blender/modifiers/CMakeLists.txt1
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_mdd.c4
-rw-r--r--source/blender/nodes/CMakeLists.txt4
-rw-r--r--source/blender/python/generic/bgl.c4
-rw-r--r--source/blender/python/gpu/gpu_py_offscreen.c2
-rw-r--r--source/blender/python/gpu/gpu_py_shader.c8
-rw-r--r--source/blender/python/intern/CMakeLists.txt1
-rw-r--r--source/blender/python/intern/bpy_rna_ui.c1
-rw-r--r--source/blender/render/CMakeLists.txt4
-rw-r--r--source/blender/shader_fx/CMakeLists.txt1
-rw-r--r--source/blender/windowmanager/CMakeLists.txt2
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c3
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c4
-rw-r--r--source/creator/CMakeLists.txt3
208 files changed, 3957 insertions, 1774 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5f1e84dd6df..602616ca286 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -546,14 +546,14 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\LLVM\\LLVM;]/lib/clang/6.0.0/lib/windows
)
elseif(APPLE)
- execute_process(COMMAND ${CMAKE_CXX_COMPILER}
- -print-file-name=lib
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER}
+ -print-file-name=lib
OUTPUT_VARIABLE CLANG_LIB_DIR
)
string(STRIP "${CLANG_LIB_DIR}" CLANG_LIB_DIR)
find_library(
COMPILER_ASAN_LIBRARY NAMES libclang_rt.asan_osx_dynamic.dylib
- PATHS
+ PATHS
"${CLANG_LIB_DIR}/darwin/"
)
unset(CLANG_LIB_DIR)
@@ -1610,7 +1610,7 @@ if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
# Make MSVC properly report the value of the __cplusplus preprocessor macro
# Available MSVC 15.7 (1914) and up, without this it reports 199711L regardless
- # of the C++ standard chosen above
+ # of the C++ standard chosen above
if(MSVC_VERSION GREATER 1913)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus")
endif()
diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h
index 57e8d17861d..1c92762ea01 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.h
+++ b/intern/ghost/intern/GHOST_SystemSDL.h
@@ -98,6 +98,6 @@ class GHOST_SystemSDL : public GHOST_System {
void processEvent(SDL_Event *sdl_event);
- /// The vector of windows that need to be updated.
+ /** The vector of windows that need to be updated. */
std::vector<GHOST_WindowSDL *> m_dirty_windows;
};
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index ef5d1755f1a..a4d17d1add3 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -225,7 +225,7 @@ class GHOST_WindowX11 : public GHOST_Window {
bool canInvertColor);
private:
- /// Force use of public constructor.
+ /* Force use of public constructor. */
GHOST_WindowX11();
diff --git a/intern/memutil/MEM_RefCounted.h b/intern/memutil/MEM_RefCounted.h
index 42e595aadf4..06828fc32c3 100644
--- a/intern/memutil/MEM_RefCounted.h
+++ b/intern/memutil/MEM_RefCounted.h
@@ -76,7 +76,7 @@ class MEM_RefCounted {
}
protected:
- /// The reference count.
+ /** The reference count. */
int m_refCount;
};
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
index 6a4b03976e4..a0bb9828bd5 100644
--- a/intern/opencolorio/ocio_impl_glsl.cc
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -95,11 +95,11 @@ struct OCIO_GLSLShader {
struct GPUShader *shader;
/** Uniform locations. */
- GLint dither_loc;
- GLint overlay_loc;
- GLint predivide_loc;
- GLint curve_mapping_loc;
- GLint ubo_bind;
+ int dither_loc;
+ int overlay_loc;
+ int predivide_loc;
+ int curve_mapping_loc;
+ int ubo_bind;
/** Error checking. */
bool valid;
};
diff --git a/release/datafiles/userdef/userdef_default_theme.c b/release/datafiles/userdef/userdef_default_theme.c
index 096e2f633d5..c837322604d 100644
--- a/release/datafiles/userdef/userdef_default_theme.c
+++ b/release/datafiles/userdef/userdef_default_theme.c
@@ -715,6 +715,7 @@ const bTheme U_theme_default = {
.paint_curve_pivot = RGBA(0xff7f7f7f),
.paint_curve_handle = RGBA(0x7fff7f7f),
.metadatatext = RGBA(0xffffffff),
+ .grid = RGBA(0x505050ff),
},
.space_text = {
.back = RGBA(0x30303000),
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index bf14d34ed20..1c31eaa39d0 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -352,16 +352,15 @@ class _GenericBone:
@property
def _other_bones(self):
id_data = self.id_data
- id_data_type = type(id_data)
- if id_data_type == bpy_types.Object:
- bones = id_data.pose.bones
- elif id_data_type == bpy_types.Armature:
- bones = id_data.edit_bones
- if not bones: # not in edit mode
- bones = id_data.bones
-
- return bones
+ # `id_data` is an 'Object' for `PosePone`, otherwise it's an `Armature`.
+ if isinstance(self, PoseBone):
+ return id_data.pose.bones
+ if isinstance(self, EditBone):
+ return id_data.edit_bones
+ if isinstance(self, Bone):
+ return id_data.bones
+ raise RuntimeError("Invalid type %r" % self)
class PoseBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index a490208fd5e..0fde128a906 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -1019,7 +1019,8 @@ class IMAGE_PT_view_display_uv_edit_overlays(Panel):
col.prop(uvedit, "show_faces", text="Faces")
col = layout.column()
- col.prop(uvedit, "show_smooth_edges", text="Smooth")
+ if context.preferences.experimental.use_image_editor_legacy_drawing:
+ col.prop(uvedit, "show_smooth_edges", text="Smooth")
col.prop(uvedit, "show_modified_edges", text="Modified")
col.prop(uvedit, "uv_opacity")
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 506849fbee5..faea806c6cb 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -2194,6 +2194,7 @@ class USERPREF_PT_experimental_debugging(ExperimentalPanel, Panel):
context, (
({"property": "use_undo_legacy"}, "T60695"),
({"property": "use_cycles_debug"}, None),
+ ({"property": "use_image_editor_legacy_drawing"}, "T67530"),
),
)
diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt
index ac927dd388d..3fd0dd95ef8 100644
--- a/source/blender/blenfont/CMakeLists.txt
+++ b/source/blender/blenfont/CMakeLists.txt
@@ -33,7 +33,6 @@ set(INC
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
${FREETYPE_INCLUDE_DIRS}
)
@@ -75,6 +74,5 @@ if(WITH_PYTHON)
)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_blenfont "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index d21fe5afa7e..fea9bbe9bb5 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -570,9 +570,9 @@ void CustomData_data_transfer(const struct MeshPairRemap *me_remap,
/* .blend file I/O */
void CustomData_blend_write_prepare(struct CustomData *data,
- struct CustomDataLayer **r_write_layers,
- struct CustomDataLayer *write_layers_buff,
- size_t write_layers_size);
+ struct CustomDataLayer **r_write_layers,
+ struct CustomDataLayer *write_layers_buff,
+ size_t write_layers_size);
void CustomData_blend_write(struct BlendWriter *writer,
struct CustomData *data,
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 88eef40ebd2..f1912b14e8c 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -48,6 +48,7 @@ struct bGPDlayer_Mask;
struct bGPDspoint;
struct bGPDstroke;
struct bGPdata;
+struct BlendDataReader;
#define GPENCIL_SIMPLIFY(scene) ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ENABLE))
#define GPENCIL_SIMPLIFY_ONPLAY(playing) \
@@ -281,6 +282,8 @@ void BKE_gpencil_parent_matrix_get(const struct Depsgraph *depsgraph,
void BKE_gpencil_update_layer_parent(const struct Depsgraph *depsgraph, struct Object *ob);
+void BKE_gpencil_blend_read_data(struct BlendDataReader *reader, struct bGPdata *gpd);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 5e8b371e604..3421aa9e900 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -254,23 +254,23 @@ typedef struct bNodeType {
* \note Used as a fallback when #bNode.label isn't set.
*/
void (*labelfunc)(struct bNodeTree *ntree, struct bNode *node, char *label, int maxlen);
- /// Optional custom resize handle polling.
+ /** Optional custom resize handle polling. */
int (*resize_area_func)(struct bNode *node, int x, int y);
- /// Optional selection area polling.
+ /** Optional selection area polling. */
int (*select_area_func)(struct bNode *node, int x, int y);
- /// Optional tweak area polling (for grabbing).
+ /** Optional tweak area polling (for grabbing). */
int (*tweak_area_func)(struct bNode *node, int x, int y);
- /// Called when the node is updated in the editor.
+ /** Called when the node is updated in the editor. */
void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node);
- /// Check and update if internal ID data has changed.
+ /** Check and update if internal ID data has changed. */
void (*group_update_func)(struct bNodeTree *ntree, struct bNode *node);
- /// Initialize a new node instance of this type after creation.
+ /** Initialize a new node instance of this type after creation. */
void (*initfunc)(struct bNodeTree *ntree, struct bNode *node);
- /// Free the node instance.
+ /** Free the node instance. */
void (*freefunc)(struct bNode *node);
- /// Make a copy of the node instance.
+ /** Make a copy of the node instance. */
void (*copyfunc)(struct bNodeTree *dest_ntree,
struct bNode *dest_node,
const struct bNode *src_node);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index cf43d0fe845..cc5226a1ab7 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -57,7 +57,6 @@ set(INC
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
${ZLIB_INCLUDE_DIRS}
)
@@ -457,7 +456,6 @@ if(WITH_BINRELOC)
add_definitions(-DWITH_BINRELOC)
endif()
-add_definitions(${GL_DEFINITIONS})
if(WIN32)
list(APPEND INC
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index f3386df03c8..9475ba7efcf 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -39,6 +39,7 @@
#include "BLT_translation.h"
+#include "BKE_anim_data.h"
#include "BKE_cachefile.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
@@ -48,6 +49,8 @@
#include "DEG_depsgraph_query.h"
+#include "BLO_read_write.h"
+
#ifdef WITH_ALEMBIC
# include "ABC_alembic.h"
#endif
@@ -85,6 +88,37 @@ static void cache_file_free_data(ID *id)
BLI_freelistN(&cache_file->object_paths);
}
+static void cache_file_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ CacheFile *cache_file = (CacheFile *)id;
+ if (cache_file->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed datablocks. */
+ BLI_listbase_clear(&cache_file->object_paths);
+ cache_file->handle = NULL;
+ memset(cache_file->handle_filepath, 0, sizeof(cache_file->handle_filepath));
+ cache_file->handle_readers = NULL;
+
+ BLO_write_id_struct(writer, CacheFile, id_address, &cache_file->id);
+
+ if (cache_file->adt) {
+ BKE_animdata_blend_write(writer, cache_file->adt);
+ }
+ }
+}
+
+static void cache_file_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ CacheFile *cache_file = (CacheFile *)id;
+ BLI_listbase_clear(&cache_file->object_paths);
+ cache_file->handle = NULL;
+ cache_file->handle_filepath[0] = '\0';
+ cache_file->handle_readers = NULL;
+
+ /* relink animdata */
+ BLO_read_data_address(reader, &cache_file->adt);
+ BKE_animdata_blend_read_data(reader, cache_file->adt);
+}
+
IDTypeInfo IDType_ID_CF = {
.id_code = ID_CF,
.id_filter = FILTER_ID_CF,
@@ -102,8 +136,8 @@ IDTypeInfo IDType_ID_CF = {
.foreach_id = NULL,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
+ .blend_write = cache_file_blend_write,
+ .blend_read_data = cache_file_blend_read_data,
.blend_read_lib = NULL,
.blend_read_expand = NULL,
};
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index e7fe10cf19c..fc1b4d82c20 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -845,7 +845,8 @@ static void childof_new_data(void *cdata)
bChildOfConstraint *data = (bChildOfConstraint *)cdata;
data->flag = (CHILDOF_LOCX | CHILDOF_LOCY | CHILDOF_LOCZ | CHILDOF_ROTX | CHILDOF_ROTY |
- CHILDOF_ROTZ | CHILDOF_SIZEX | CHILDOF_SIZEY | CHILDOF_SIZEZ);
+ CHILDOF_ROTZ | CHILDOF_SIZEX | CHILDOF_SIZEY | CHILDOF_SIZEZ |
+ CHILDOF_SET_INVERSE);
unit_m4(data->invmat);
}
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 1e37ae3892b..03ac7e622e1 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -40,12 +40,16 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_gpencil_types.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_space_types.h"
#include "BKE_action.h"
+#include "BKE_anim_data.h"
#include "BKE_collection.h"
#include "BKE_colortools.h"
#include "BKE_deform.h"
@@ -64,6 +68,10 @@
#include "DEG_depsgraph_query.h"
+#include "BLO_read_write.h"
+
+#include "BKE_gpencil.h"
+
static CLG_LogRef LOG = {"bke.gpencil"};
static void greasepencil_copy_data(Main *UNUSED(bmain),
@@ -111,6 +119,154 @@ static void greasepencil_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void greasepencil_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ bGPdata *gpd = (bGPdata *)id;
+ if (gpd->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed data-blocks. */
+ /* XXX not sure why the whole run-time data is not cleared in reading code,
+ * for now mimicking it here. */
+ gpd->runtime.sbuffer = NULL;
+ gpd->runtime.sbuffer_used = 0;
+ gpd->runtime.sbuffer_size = 0;
+ gpd->runtime.tot_cp_points = 0;
+
+ /* write gpd data block to file */
+ BLO_write_id_struct(writer, bGPdata, id_address, &gpd->id);
+ BKE_id_blend_write(writer, &gpd->id);
+
+ if (gpd->adt) {
+ BKE_animdata_blend_write(writer, gpd->adt);
+ }
+
+ BLO_write_pointer_array(writer, gpd->totcol, gpd->mat);
+
+ /* write grease-pencil layers to file */
+ BLO_write_struct_list(writer, bGPDlayer, &gpd->layers);
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* Write mask list. */
+ BLO_write_struct_list(writer, bGPDlayer_Mask, &gpl->mask_layers);
+ /* write this layer's frames to file */
+ BLO_write_struct_list(writer, bGPDframe, &gpl->frames);
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ /* write strokes */
+ BLO_write_struct_list(writer, bGPDstroke, &gpf->strokes);
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ BLO_write_struct_array(writer, bGPDspoint, gps->totpoints, gps->points);
+ BLO_write_struct_array(writer, bGPDtriangle, gps->tot_triangles, gps->triangles);
+ BKE_defvert_blend_write(writer, gps->totpoints, gps->dvert);
+ }
+ }
+ }
+ }
+}
+
+void BKE_gpencil_blend_read_data(BlendDataReader *reader, bGPdata *gpd)
+{
+ /* we must firstly have some grease-pencil data to link! */
+ if (gpd == NULL) {
+ return;
+ }
+
+ /* relink animdata */
+ BLO_read_data_address(reader, &gpd->adt);
+ BKE_animdata_blend_read_data(reader, gpd->adt);
+
+ /* Ensure full objectmode for linked grease pencil. */
+ if (gpd->id.lib != NULL) {
+ gpd->flag &= ~GP_DATA_STROKE_PAINTMODE;
+ gpd->flag &= ~GP_DATA_STROKE_EDITMODE;
+ gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE;
+ gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE;
+ gpd->flag &= ~GP_DATA_STROKE_VERTEXMODE;
+ }
+
+ /* init stroke buffer */
+ gpd->runtime.sbuffer = NULL;
+ gpd->runtime.sbuffer_used = 0;
+ gpd->runtime.sbuffer_size = 0;
+ gpd->runtime.tot_cp_points = 0;
+
+ /* relink palettes (old palettes deprecated, only to convert old files) */
+ BLO_read_list(reader, &gpd->palettes);
+ if (gpd->palettes.first != NULL) {
+ LISTBASE_FOREACH (Palette *, palette, &gpd->palettes) {
+ BLO_read_list(reader, &palette->colors);
+ }
+ }
+
+ /* materials */
+ BLO_read_pointer_array(reader, (void **)&gpd->mat);
+
+ /* relink layers */
+ BLO_read_list(reader, &gpd->layers);
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* relink frames */
+ BLO_read_list(reader, &gpl->frames);
+
+ BLO_read_data_address(reader, &gpl->actframe);
+
+ gpl->runtime.icon_id = 0;
+
+ /* Relink masks. */
+ BLO_read_list(reader, &gpl->mask_layers);
+
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ /* relink strokes (and their points) */
+ BLO_read_list(reader, &gpf->strokes);
+
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ /* relink stroke points array */
+ BLO_read_data_address(reader, &gps->points);
+ /* Relink geometry*/
+ BLO_read_data_address(reader, &gps->triangles);
+
+ /* relink weight data */
+ if (gps->dvert) {
+ BLO_read_data_address(reader, &gps->dvert);
+ BKE_defvert_blend_read(reader, gps->totpoints, gps->dvert);
+ }
+ }
+ }
+ }
+}
+
+static void greasepencil_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ bGPdata *gpd = (bGPdata *)id;
+ BKE_gpencil_blend_read_data(reader, gpd);
+}
+
+static void greasepencil_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ bGPdata *gpd = (bGPdata *)id;
+
+ /* Relink all data-lock linked by GP data-lock */
+ /* Layers */
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* Layer -> Parent References */
+ BLO_read_id_address(reader, gpd->id.lib, &gpl->parent);
+ }
+
+ /* materials */
+ for (int a = 0; a < gpd->totcol; a++) {
+ BLO_read_id_address(reader, gpd->id.lib, &gpd->mat[a]);
+ }
+}
+
+static void greasepencil_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ bGPdata *gpd = (bGPdata *)id;
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ BLO_expand(expander, gpl->parent);
+ }
+
+ for (int a = 0; a < gpd->totcol; a++) {
+ BLO_expand(expander, gpd->mat[a]);
+ }
+}
+
IDTypeInfo IDType_ID_GD = {
.id_code = ID_GD,
.id_filter = FILTER_ID_GD,
@@ -128,10 +284,10 @@ IDTypeInfo IDType_ID_GD = {
.foreach_id = greasepencil_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = greasepencil_blend_write,
+ .blend_read_data = greasepencil_blend_read_data,
+ .blend_read_lib = greasepencil_blend_read_lib,
+ .blend_read_expand = greasepencil_blend_read_expand,
};
/* ************************************************** */
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index 83e3a3098e9..a9b0eede055 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -2264,17 +2264,16 @@ static int gpencil_material_find_index_by_name(Object *ob, const char *name)
return -1;
}
-/* Create the name with the object name and a subfix. */
-static void make_element_name(char *obname, char *name, const int maxlen, char *r_name)
+/**
+ * Create the name with the object name and a suffix.
+ */
+static void make_element_name(const char *obname, const char *name, const int maxlen, char *r_name)
{
char str[256];
- sprintf(str, "%s_%s", obname, name);
+ SNPRINTF(str, "%s_%s", obname, name);
+
/* Replace any point by underscore. */
- char *current_pos = strchr(str, '.');
- while (current_pos) {
- *current_pos = '_';
- current_pos = strchr(current_pos, '.');
- }
+ BLI_str_replace_char(str, '.', '_');
BLI_strncpy_utf8(r_name, str, maxlen);
}
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 314b7228373..57997eaf3a1 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -47,8 +47,10 @@
#include "DEG_depsgraph_query.h"
-const char *HAIR_ATTR_POSITION = "Position";
-const char *HAIR_ATTR_RADIUS = "Radius";
+#include "BLO_read_write.h"
+
+static const char *HAIR_ATTR_POSITION = "Position";
+static const char *HAIR_ATTR_RADIUS = "Radius";
/* Hair datablock */
@@ -109,6 +111,69 @@ static void hair_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void hair_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Hair *hair = (Hair *)id;
+ if (hair->id.us > 0 || BLO_write_is_undo(writer)) {
+ CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
+ CustomDataLayer *clayers = NULL, clayers_buff[CD_TEMP_CHUNK_SIZE];
+ CustomData_blend_write_prepare(&hair->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
+ CustomData_blend_write_prepare(&hair->cdata, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff));
+
+ /* Write LibData */
+ BLO_write_id_struct(writer, Hair, id_address, &hair->id);
+ BKE_id_blend_write(writer, &hair->id);
+
+ /* Direct data */
+ CustomData_blend_write(writer, &hair->pdata, players, hair->totpoint, CD_MASK_ALL, &hair->id);
+ CustomData_blend_write(writer, &hair->cdata, clayers, hair->totcurve, CD_MASK_ALL, &hair->id);
+
+ BLO_write_pointer_array(writer, hair->totcol, hair->mat);
+ if (hair->adt) {
+ BKE_animdata_blend_write(writer, hair->adt);
+ }
+
+ /* Remove temporary data. */
+ if (players && players != players_buff) {
+ MEM_freeN(players);
+ }
+ if (clayers && clayers != clayers_buff) {
+ MEM_freeN(clayers);
+ }
+ }
+}
+
+static void hair_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Hair *hair = (Hair *)id;
+ BLO_read_data_address(reader, &hair->adt);
+ BKE_animdata_blend_read_data(reader, hair->adt);
+
+ /* Geometry */
+ CustomData_blend_read(reader, &hair->pdata, hair->totpoint);
+ CustomData_blend_read(reader, &hair->cdata, hair->totcurve);
+ BKE_hair_update_customdata_pointers(hair);
+
+ /* Materials */
+ BLO_read_pointer_array(reader, (void **)&hair->mat);
+}
+
+static void hair_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Hair *hair = (Hair *)id;
+ for (int a = 0; a < hair->totcol; a++) {
+ BLO_read_id_address(reader, hair->id.lib, &hair->mat[a]);
+ }
+}
+
+static void hair_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Hair *hair = (Hair *)id;
+ for (int a = 0; a < hair->totcol; a++) {
+ BLO_expand(expander, hair->mat[a]);
+ }
+}
+
IDTypeInfo IDType_ID_HA = {
.id_code = ID_HA,
.id_filter = FILTER_ID_HA,
@@ -126,10 +191,10 @@ IDTypeInfo IDType_ID_HA = {
.foreach_id = hair_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = hair_blend_write,
+ .blend_read_data = hair_blend_read_data,
+ .blend_read_lib = hair_blend_read_lib,
+ .blend_read_expand = hair_blend_read_expand,
};
static void hair_random(Hair *hair)
diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c
index d4a1c1e2c46..f37e038e69e 100644
--- a/source/blender/blenkernel/intern/image_gpu.c
+++ b/source/blender/blenkernel/intern/image_gpu.c
@@ -272,6 +272,13 @@ static GPUTexture *image_get_gpu_texture(Image *ima,
* context and might as well ensure we have as much space free as possible. */
gpu_free_unused_buffers();
+ /* Free GPU textures when requesting a different render pass/layer. */
+ if (ima->gpu_pass != iuser->pass || ima->gpu_layer != iuser->layer) {
+ ima->gpu_pass = iuser->pass;
+ ima->gpu_layer = iuser->layer;
+ ima->gpuflag |= IMA_GPU_REFRESH;
+ }
+
/* currently, gpu refresh tagging is used by ima sequences */
if (ima->gpuflag & IMA_GPU_REFRESH) {
image_free_gpu(ima, true);
@@ -282,7 +289,10 @@ static GPUTexture *image_get_gpu_texture(Image *ima,
BKE_image_tag_time(ima);
/* Test if we already have a texture. */
- GPUTexture **tex = get_image_gpu_texture_ptr(ima, textarget, iuser ? iuser->multiview_eye : 0);
+ const int current_view = iuser ? ((iuser->flag & IMA_SHOW_STEREO) != 0 ? iuser->multiview_eye :
+ iuser->view) :
+ 0;
+ GPUTexture **tex = get_image_gpu_texture_ptr(ima, textarget, current_view);
if (*tex) {
return *tex;
}
diff --git a/source/blender/blenkernel/intern/pointcloud.c b/source/blender/blenkernel/intern/pointcloud.c
index 087bf123575..6ec305a971c 100644
--- a/source/blender/blenkernel/intern/pointcloud.c
+++ b/source/blender/blenkernel/intern/pointcloud.c
@@ -47,12 +47,14 @@
#include "DEG_depsgraph_query.h"
+#include "BLO_read_write.h"
+
/* PointCloud datablock */
static void pointcloud_random(PointCloud *pointcloud);
-const char *POINTCLOUD_ATTR_POSITION = "Position";
-const char *POINTCLOUD_ATTR_RADIUS = "Radius";
+static const char *POINTCLOUD_ATTR_POSITION = "Position";
+static const char *POINTCLOUD_ATTR_RADIUS = "Radius";
static void pointcloud_init_data(ID *id)
{
@@ -111,6 +113,64 @@ static void pointcloud_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void pointcloud_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ PointCloud *pointcloud = (PointCloud *)id;
+ if (pointcloud->id.us > 0 || BLO_write_is_undo(writer)) {
+ CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
+ CustomData_blend_write_prepare(
+ &pointcloud->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
+
+ /* Write LibData */
+ BLO_write_id_struct(writer, PointCloud, id_address, &pointcloud->id);
+ BKE_id_blend_write(writer, &pointcloud->id);
+
+ /* Direct data */
+ CustomData_blend_write(
+ writer, &pointcloud->pdata, players, pointcloud->totpoint, CD_MASK_ALL, &pointcloud->id);
+
+ BLO_write_pointer_array(writer, pointcloud->totcol, pointcloud->mat);
+ if (pointcloud->adt) {
+ BKE_animdata_blend_write(writer, pointcloud->adt);
+ }
+
+ /* Remove temporary data. */
+ if (players && players != players_buff) {
+ MEM_freeN(players);
+ }
+ }
+}
+
+static void pointcloud_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ PointCloud *pointcloud = (PointCloud *)id;
+ BLO_read_data_address(reader, &pointcloud->adt);
+ BKE_animdata_blend_read_data(reader, pointcloud->adt);
+
+ /* Geometry */
+ CustomData_blend_read(reader, &pointcloud->pdata, pointcloud->totpoint);
+ BKE_pointcloud_update_customdata_pointers(pointcloud);
+
+ /* Materials */
+ BLO_read_pointer_array(reader, (void **)&pointcloud->mat);
+}
+
+static void pointcloud_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ PointCloud *pointcloud = (PointCloud *)id;
+ for (int a = 0; a < pointcloud->totcol; a++) {
+ BLO_read_id_address(reader, pointcloud->id.lib, &pointcloud->mat[a]);
+ }
+}
+
+static void pointcloud_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ PointCloud *pointcloud = (PointCloud *)id;
+ for (int a = 0; a < pointcloud->totcol; a++) {
+ BLO_expand(expander, pointcloud->mat[a]);
+ }
+}
+
IDTypeInfo IDType_ID_PT = {
.id_code = ID_PT,
.id_filter = FILTER_ID_PT,
@@ -128,10 +188,10 @@ IDTypeInfo IDType_ID_PT = {
.foreach_id = pointcloud_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = pointcloud_blend_write,
+ .blend_read_data = pointcloud_blend_read_data,
+ .blend_read_lib = pointcloud_blend_read_lib,
+ .blend_read_expand = pointcloud_blend_read_expand,
};
static void pointcloud_random(PointCloud *pointcloud)
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index 9dc1f073e2a..f08051510db 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -63,6 +63,8 @@
#include "SIM_simulation_update.hh"
+#include "BLO_read_write.h"
+
using StateInitFunction = void (*)(SimulationState *state);
using StateResetFunction = void (*)(SimulationState *state);
using StateRemoveFunction = void (*)(SimulationState *state);
@@ -145,6 +147,94 @@ static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
+static void simulation_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Simulation *simulation = (Simulation *)id;
+ if (simulation->id.us > 0 || BLO_write_is_undo(writer)) {
+ BLO_write_id_struct(writer, Simulation, id_address, &simulation->id);
+ BKE_id_blend_write(writer, &simulation->id);
+
+ if (simulation->adt) {
+ BKE_animdata_blend_write(writer, simulation->adt);
+ }
+
+ /* nodetree is integral part of simulation, no libdata */
+ if (simulation->nodetree) {
+ BLO_write_struct(writer, bNodeTree, simulation->nodetree);
+ ntreeBlendWrite(writer, simulation->nodetree);
+ }
+
+ LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
+ BLO_write_string(writer, state->name);
+ BLO_write_string(writer, state->type);
+ /* TODO: Decentralize this part. */
+ if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) {
+ ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
+
+ CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
+ CustomData_blend_write_prepare(
+ &particle_state->attributes, &players, players_buff, ARRAY_SIZE(players_buff));
+
+ BLO_write_struct(writer, ParticleSimulationState, particle_state);
+
+ CustomData_blend_write(writer,
+ &particle_state->attributes,
+ players,
+ particle_state->tot_particles,
+ CD_MASK_ALL,
+ &simulation->id);
+
+ /* Remove temporary data. */
+ if (players && players != players_buff) {
+ MEM_freeN(players);
+ }
+ }
+ else if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER)) {
+ ParticleMeshEmitterSimulationState *emitter_state = (ParticleMeshEmitterSimulationState *)
+ state;
+ BLO_write_struct(writer, ParticleMeshEmitterSimulationState, emitter_state);
+ }
+ }
+
+ BLO_write_struct_list(writer, SimulationDependency, &simulation->dependencies);
+ }
+}
+
+static void simulation_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Simulation *simulation = (Simulation *)id;
+ BLO_read_data_address(reader, &simulation->adt);
+ BKE_animdata_blend_read_data(reader, simulation->adt);
+
+ BLO_read_list(reader, &simulation->states);
+ LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
+ BLO_read_data_address(reader, &state->name);
+ BLO_read_data_address(reader, &state->type);
+ if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) {
+ ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
+ CustomData_blend_read(reader, &particle_state->attributes, particle_state->tot_particles);
+ }
+ }
+
+ BLO_read_list(reader, &simulation->dependencies);
+}
+
+static void simulation_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Simulation *simulation = (Simulation *)id;
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
+ BLO_read_id_address(reader, simulation->id.lib, &dependency->id);
+ }
+}
+
+static void simulation_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Simulation *simulation = (Simulation *)id;
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
+ BLO_expand(expander, dependency->id);
+ }
+}
+
IDTypeInfo IDType_ID_SIM = {
/* id_code */ ID_SIM,
/* id_filter */ FILTER_ID_SIM,
@@ -162,10 +252,10 @@ IDTypeInfo IDType_ID_SIM = {
/* foreach_id */ simulation_foreach_id,
/* foreach_cache */ NULL,
- /* blend_write */ NULL,
- /* blend_read_data */ NULL,
- /* blend_read_lib */ NULL,
- /* blend_read_expand */ NULL,
+ /* blend_write */ simulation_blend_write,
+ /* blend_read_data */ simulation_blend_read_data,
+ /* blend_read_lib */ simulation_blend_read_lib,
+ /* blend_read_expand */ simulation_blend_read_expand,
};
void *BKE_simulation_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 88b32e194cf..9cf5ef85850 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -3014,7 +3014,7 @@ static void curve_surf_to_softbody(Scene *scene, Object *ob)
*
* a: never ever make tangent handles (sub) and or (ob)ject to collision.
* b: rather calculate them using some C2
- * (C2= continuous in second derivate -> no jump in bending ) condition.
+ * (C2= continuous in second derivative -> no jump in bending ) condition.
*
* Not too hard to do, but needs some more code to care for;
* some one may want look at it (JOW 2010/06/12). */
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 8ee6a3627dc..c8a31b51500 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -33,6 +33,9 @@
#include "BLT_translation.h"
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_packedFile_types.h"
@@ -63,6 +66,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "BLO_read_write.h"
+
static void sound_free_audio(bSound *sound);
static void sound_copy_data(Main *UNUSED(bmain),
@@ -126,6 +131,64 @@ static void sound_foreach_cache(ID *id,
function_callback(id, &key, &sound->waveform, 0, user_data);
}
+static void sound_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ bSound *sound = (bSound *)id;
+ if (sound->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed datablocks. */
+ sound->tags = 0;
+ sound->handle = NULL;
+ sound->playback_handle = NULL;
+ sound->spinlock = NULL;
+
+ /* write LibData */
+ BLO_write_id_struct(writer, bSound, id_address, &sound->id);
+ BKE_id_blend_write(writer, &sound->id);
+
+ BKE_packedfile_blend_write(writer, sound->packedfile);
+ }
+}
+
+static void sound_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ bSound *sound = (bSound *)id;
+ sound->tags = 0;
+ sound->handle = NULL;
+ sound->playback_handle = NULL;
+
+ /* versioning stuff, if there was a cache, then we enable caching: */
+ if (sound->cache) {
+ sound->flags |= SOUND_FLAGS_CACHING;
+ sound->cache = NULL;
+ }
+
+ if (BLO_read_data_is_undo(reader)) {
+ sound->tags |= SOUND_TAGS_WAVEFORM_NO_RELOAD;
+ }
+
+ sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
+ BLI_spin_init(sound->spinlock);
+
+ /* clear waveform loading flag */
+ sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
+
+ BKE_packedfile_blend_read(reader, &sound->packedfile);
+ BKE_packedfile_blend_read(reader, &sound->newpackedfile);
+}
+
+static void sound_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ bSound *sound = (bSound *)id;
+ BLO_read_id_address(
+ reader, sound->id.lib, &sound->ipo); // XXX deprecated - old animation system
+}
+
+static void sound_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ bSound *snd = (bSound *)id;
+ BLO_expand(expander, snd->ipo); // XXX deprecated - old animation system
+}
+
IDTypeInfo IDType_ID_SO = {
.id_code = ID_SO,
.id_filter = FILTER_ID_SO,
@@ -144,10 +207,10 @@ IDTypeInfo IDType_ID_SO = {
.foreach_id = NULL,
.foreach_cache = sound_foreach_cache,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = sound_blend_write,
+ .blend_read_data = sound_blend_read_data,
+ .blend_read_lib = sound_blend_read_lib,
+ .blend_read_expand = sound_blend_read_expand,
};
#ifdef WITH_AUDASPACE
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 9e176f355d3..698f6b8cffd 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -36,6 +36,9 @@
#include "BLT_translation.h"
+/* Allow using deprecated functionality for .blend file I/O. */
+#define DNA_DEPRECATED_ALLOW
+
#include "DNA_brush_types.h"
#include "DNA_color_types.h"
#include "DNA_defaults.h"
@@ -50,6 +53,7 @@
#include "BKE_main.h"
+#include "BKE_anim_data.h"
#include "BKE_colorband.h"
#include "BKE_colortools.h"
#include "BKE_icons.h"
@@ -65,6 +69,8 @@
#include "RE_shader_ext.h"
+#include "BLO_read_write.h"
+
static void texture_init_data(ID *id)
{
Tex *texture = (Tex *)id;
@@ -134,6 +140,62 @@ static void texture_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS(data, texture->ima, IDWALK_CB_USER);
}
+static void texture_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Tex *tex = (Tex *)id;
+ if (tex->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* write LibData */
+ BLO_write_id_struct(writer, Tex, id_address, &tex->id);
+ BKE_id_blend_write(writer, &tex->id);
+
+ if (tex->adt) {
+ BKE_animdata_blend_write(writer, tex->adt);
+ }
+
+ /* direct data */
+ if (tex->coba) {
+ BLO_write_struct(writer, ColorBand, tex->coba);
+ }
+
+ /* nodetree is integral part of texture, no libdata */
+ if (tex->nodetree) {
+ BLO_write_struct(writer, bNodeTree, tex->nodetree);
+ ntreeBlendWrite(writer, tex->nodetree);
+ }
+
+ BKE_previewimg_blend_write(writer, tex->preview);
+ }
+}
+
+static void texture_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Tex *tex = (Tex *)id;
+ BLO_read_data_address(reader, &tex->adt);
+ BKE_animdata_blend_read_data(reader, tex->adt);
+
+ BLO_read_data_address(reader, &tex->coba);
+
+ BLO_read_data_address(reader, &tex->preview);
+ BKE_previewimg_blend_read(reader, tex->preview);
+
+ tex->iuser.ok = 1;
+ tex->iuser.scene = NULL;
+}
+
+static void texture_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Tex *tex = (Tex *)id;
+ BLO_read_id_address(reader, tex->id.lib, &tex->ima);
+ BLO_read_id_address(reader, tex->id.lib, &tex->ipo); // XXX deprecated - old animation system
+}
+
+static void texture_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Tex *tex = (Tex *)id;
+ BLO_expand(expander, tex->ima);
+ BLO_expand(expander, tex->ipo); // XXX deprecated - old animation system
+}
+
IDTypeInfo IDType_ID_TE = {
.id_code = ID_TE,
.id_filter = FILTER_ID_TE,
@@ -151,10 +213,10 @@ IDTypeInfo IDType_ID_TE = {
.foreach_id = texture_foreach_id,
.foreach_cache = NULL,
- .blend_write = NULL,
- .blend_read_data = NULL,
- .blend_read_lib = NULL,
- .blend_read_expand = NULL,
+ .blend_write = texture_blend_write,
+ .blend_read_data = texture_blend_read_data,
+ .blend_read_lib = texture_blend_read_lib,
+ .blend_read_expand = texture_blend_read_expand,
};
/* Utils for all IDs using those texture slots. */
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index f99be2f6aee..eb871e41f8e 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -51,6 +51,8 @@
#include "DEG_depsgraph_query.h"
+#include "BLO_read_write.h"
+
#include "CLG_log.h"
#ifdef WITH_OPENVDB
@@ -509,6 +511,61 @@ static void volume_foreach_cache(ID *id,
function_callback(id, &key, (void **)&volume->runtime.grids, 0, user_data);
}
+static void volume_blend_write(BlendWriter *writer, ID *id, const void *id_address)
+{
+ Volume *volume = (Volume *)id;
+ if (volume->id.us > 0 || BLO_write_is_undo(writer)) {
+ /* Clean up, important in undo case to reduce false detection of changed datablocks. */
+ volume->runtime.grids = 0;
+
+ /* write LibData */
+ BLO_write_id_struct(writer, Volume, id_address, &volume->id);
+ BKE_id_blend_write(writer, &volume->id);
+
+ /* direct data */
+ BLO_write_pointer_array(writer, volume->totcol, volume->mat);
+ if (volume->adt) {
+ BKE_animdata_blend_write(writer, volume->adt);
+ }
+
+ BKE_packedfile_blend_write(writer, volume->packedfile);
+ }
+}
+
+static void volume_blend_read_data(BlendDataReader *reader, ID *id)
+{
+ Volume *volume = (Volume *)id;
+ BLO_read_data_address(reader, &volume->adt);
+ BKE_animdata_blend_read_data(reader, volume->adt);
+
+ BKE_packedfile_blend_read(reader, &volume->packedfile);
+ volume->runtime.frame = 0;
+
+ /* materials */
+ BLO_read_pointer_array(reader, (void **)&volume->mat);
+}
+
+static void volume_blend_read_lib(BlendLibReader *reader, ID *id)
+{
+ Volume *volume = (Volume *)id;
+ /* Needs to be done *after* cache pointers are restored (call to
+ * `foreach_cache`/`blo_cache_storage_entry_restore_in_new`), easier for now to do it in
+ * lib_link... */
+ BKE_volume_init_grids(volume);
+
+ for (int a = 0; a < volume->totcol; a++) {
+ BLO_read_id_address(reader, volume->id.lib, &volume->mat[a]);
+ }
+}
+
+static void volume_blend_read_expand(BlendExpander *expander, ID *id)
+{
+ Volume *volume = (Volume *)id;
+ for (int a = 0; a < volume->totcol; a++) {
+ BLO_expand(expander, volume->mat[a]);
+ }
+}
+
IDTypeInfo IDType_ID_VO = {
/* id_code */ ID_VO,
/* id_filter */ FILTER_ID_VO,
@@ -526,10 +583,10 @@ IDTypeInfo IDType_ID_VO = {
/* foreach_id */ volume_foreach_id,
/* foreach_cache */ volume_foreach_cache,
- /* blend_write */ NULL,
- /* blend_read_data */ NULL,
- /* blend_read_lib */ NULL,
- /* blend_read_expand */ NULL,
+ /* blend_write */ volume_blend_write,
+ /* blend_read_data */ volume_blend_read_data,
+ /* blend_read_lib */ volume_blend_read_lib,
+ /* blend_read_expand */ volume_blend_read_expand,
};
void BKE_volume_init_grids(Volume *volume)
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index f030a733752..73f8c2717b0 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -202,7 +202,7 @@ const float bvhtree_kdop_axes[13][3] = {
};
/* Used to correct the epsilon and thus match the overlap distance. */
-const float bvhtree_kdop_axes_length[13] = {
+static const float bvhtree_kdop_axes_length[13] = {
1.0f,
1.0f,
1.0f,
diff --git a/source/blender/blenlib/intern/math_bits_inline.c b/source/blender/blenlib/intern/math_bits_inline.c
index 3a0cea182ba..ba18bb73850 100644
--- a/source/blender/blenlib/intern/math_bits_inline.c
+++ b/source/blender/blenlib/intern/math_bits_inline.c
@@ -48,7 +48,7 @@ MINLINE unsigned int bitscan_forward_uint64(unsigned long long a)
_BitScanForward64(&ctz, a);
return ctz;
#else
- return (unsigned int)__builtin_ctz(a);
+ return (unsigned int)__builtin_ctzll(a);
#endif
}
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 08c7d3b1e91..6727e6a337d 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -2616,9 +2616,9 @@ void print_m4(const char *str, const float m[4][4])
*
* Compute the Single Value Decomposition of an arbitrary matrix A
* That is compute the 3 matrices U,W,V with U column orthogonal (m,n)
- * ,W a diagonal matrix and V an orthogonal square matrix s.t.
- * A = U.W.Vt. From this decomposition it is trivial to compute the
- * (pseudo-inverse) of A as Ainv = V.Winv.tranpose(U).
+ * ,W a diagonal matrix and V an orthogonal square matrix `s.t.A = U.W.Vt`.
+ * From this decomposition it is trivial to compute the (pseudo-inverse)
+ * of `A` as `Ainv = V.Winv.transpose(U)`.
*/
void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4])
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 18a6e8a3525..6328c887063 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1300,7 +1300,7 @@ void BLI_setenv_if_new(const char *env, const char *val)
/**
* Get an env var, result has to be used immediately.
*
-* On windows getenv gets its variables from a static copy of the environment variables taken at
+ * On windows getenv gets its variables from a static copy of the environment variables taken at
* process start-up, causing it to not pick up on environment variables created during runtime.
* This function uses an alternative method to get environment variables that does pick up on
* runtime environment variables.
diff --git a/source/blender/blenloader/BLO_read_write.h b/source/blender/blenloader/BLO_read_write.h
index e05c1046b95..8a6811444af 100644
--- a/source/blender/blenloader/BLO_read_write.h
+++ b/source/blender/blenloader/BLO_read_write.h
@@ -210,7 +210,7 @@ bool BLO_read_data_is_undo(BlendDataReader *reader);
ID *BLO_read_get_new_id_address(BlendLibReader *reader, struct Library *lib, struct ID *id);
#define BLO_read_id_address(reader, lib, id_ptr_p) \
- *(id_ptr_p) = (void *)BLO_read_get_new_id_address((reader), (lib), (ID *)*(id_ptr_p))
+ *((void **)id_ptr_p) = (void *)BLO_read_get_new_id_address((reader), (lib), (ID *)*(id_ptr_p))
/* Misc. */
bool BLO_read_lib_is_undo(BlendLibReader *reader);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 095fee74f39..d013006b602 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -127,6 +127,7 @@
#include "BKE_fcurve_driver.h"
#include "BKE_fluid.h"
#include "BKE_global.h" // for G
+#include "BKE_gpencil.h"
#include "BKE_gpencil_modifier.h"
#include "BKE_hair.h"
#include "BKE_icons.h"
@@ -2537,28 +2538,6 @@ static void lib_link_constraint_channels(BlendLibReader *reader, ID *id, ListBas
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Read ID: CacheFiles
- * \{ */
-
-static void lib_link_cachefiles(BlendLibReader *UNUSED(reader), CacheFile *UNUSED(cache_file))
-{
-}
-
-static void direct_link_cachefile(BlendDataReader *reader, CacheFile *cache_file)
-{
- BLI_listbase_clear(&cache_file->object_paths);
- cache_file->handle = NULL;
- cache_file->handle_filepath[0] = '\0';
- cache_file->handle_readers = NULL;
-
- /* relink animdata */
- BLO_read_data_address(reader, &cache_file->adt);
- BKE_animdata_blend_read_data(reader, cache_file->adt);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Read ID: WorkSpace
* \{ */
@@ -2804,32 +2783,6 @@ void blo_do_versions_key_uidgen(Key *key)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Read ID: Texture
- * \{ */
-
-static void lib_link_texture(BlendLibReader *reader, Tex *tex)
-{
- BLO_read_id_address(reader, tex->id.lib, &tex->ima);
- BLO_read_id_address(reader, tex->id.lib, &tex->ipo); // XXX deprecated - old animation system
-}
-
-static void direct_link_texture(BlendDataReader *reader, Tex *tex)
-{
- BLO_read_data_address(reader, &tex->adt);
- BKE_animdata_blend_read_data(reader, tex->adt);
-
- BLO_read_data_address(reader, &tex->coba);
-
- BLO_read_data_address(reader, &tex->preview);
- BKE_previewimg_blend_read(reader, tex->preview);
-
- tex->iuser.ok = 1;
- tex->iuser.scene = NULL;
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Read ID: Particle Settings
* \{ */
@@ -4947,100 +4900,6 @@ static void direct_link_scene(BlendDataReader *reader, Scene *sce)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Read ID: Grease Pencil
- * \{ */
-
-/* relink's grease pencil data's refs */
-static void lib_link_gpencil(BlendLibReader *reader, bGPdata *gpd)
-{
- /* Relink all data-lock linked by GP data-lock */
- /* Layers */
- LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- /* Layer -> Parent References */
- BLO_read_id_address(reader, gpd->id.lib, &gpl->parent);
- }
-
- /* materials */
- for (int a = 0; a < gpd->totcol; a++) {
- BLO_read_id_address(reader, gpd->id.lib, &gpd->mat[a]);
- }
-}
-
-/* relinks grease-pencil data - used for direct_link and old file linkage */
-static void direct_link_gpencil(BlendDataReader *reader, bGPdata *gpd)
-{
- /* we must firstly have some grease-pencil data to link! */
- if (gpd == NULL) {
- return;
- }
-
- /* relink animdata */
- BLO_read_data_address(reader, &gpd->adt);
- BKE_animdata_blend_read_data(reader, gpd->adt);
-
- /* Ensure full objectmode for linked grease pencil. */
- if (gpd->id.lib != NULL) {
- gpd->flag &= ~GP_DATA_STROKE_PAINTMODE;
- gpd->flag &= ~GP_DATA_STROKE_EDITMODE;
- gpd->flag &= ~GP_DATA_STROKE_SCULPTMODE;
- gpd->flag &= ~GP_DATA_STROKE_WEIGHTMODE;
- gpd->flag &= ~GP_DATA_STROKE_VERTEXMODE;
- }
-
- /* init stroke buffer */
- gpd->runtime.sbuffer = NULL;
- gpd->runtime.sbuffer_used = 0;
- gpd->runtime.sbuffer_size = 0;
- gpd->runtime.tot_cp_points = 0;
-
- /* relink palettes (old palettes deprecated, only to convert old files) */
- BLO_read_list(reader, &gpd->palettes);
- if (gpd->palettes.first != NULL) {
- LISTBASE_FOREACH (Palette *, palette, &gpd->palettes) {
- BLO_read_list(reader, &palette->colors);
- }
- }
-
- /* materials */
- BLO_read_pointer_array(reader, (void **)&gpd->mat);
-
- /* relink layers */
- BLO_read_list(reader, &gpd->layers);
-
- LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- /* relink frames */
- BLO_read_list(reader, &gpl->frames);
-
- BLO_read_data_address(reader, &gpl->actframe);
-
- gpl->runtime.icon_id = 0;
-
- /* Relink masks. */
- BLO_read_list(reader, &gpl->mask_layers);
-
- LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
- /* relink strokes (and their points) */
- BLO_read_list(reader, &gpf->strokes);
-
- LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
- /* relink stroke points array */
- BLO_read_data_address(reader, &gps->points);
- /* Relink geometry*/
- BLO_read_data_address(reader, &gps->triangles);
-
- /* relink weight data */
- if (gps->dvert) {
- BLO_read_data_address(reader, &gps->dvert);
- BKE_defvert_blend_read(reader, gps->totpoints, gps->dvert);
- }
- }
- }
- }
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Read Screen Area/Region (Screen Data)
* \{ */
@@ -5185,7 +5044,7 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
if (v3d->gpd) {
BLO_read_data_address(reader, &v3d->gpd);
- direct_link_gpencil(reader, v3d->gpd);
+ BKE_gpencil_blend_read_data(reader, v3d->gpd);
}
BLO_read_data_address(reader, &v3d->localvd);
@@ -5257,7 +5116,7 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
#if 0
sima->gpd = newdataadr(fd, sima->gpd);
if (sima->gpd) {
- direct_link_gpencil(fd, sima->gpd);
+ BKE_gpencil_blend_read_data(fd, sima->gpd);
}
#endif
}
@@ -5266,7 +5125,7 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
if (snode->gpd) {
BLO_read_data_address(reader, &snode->gpd);
- direct_link_gpencil(reader, snode->gpd);
+ BKE_gpencil_blend_read_data(reader, snode->gpd);
}
BLO_read_list(reader, &snode->treepath);
@@ -5291,7 +5150,7 @@ static void direct_link_area(BlendDataReader *reader, ScrArea *area)
#if 0
if (sseq->gpd) {
sseq->gpd = newdataadr(fd, sseq->gpd);
- direct_link_gpencil(fd, sseq->gpd);
+ BKE_gpencil_blend_read_data(fd, sseq->gpd);
}
#endif
sseq->scopes.reference_ibuf = NULL;
@@ -6324,158 +6183,6 @@ static void fix_relpaths_library(const char *basepath, Main *main)
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Read ID: Sound
- * \{ */
-
-static void direct_link_sound(BlendDataReader *reader, bSound *sound)
-{
- sound->tags = 0;
- sound->handle = NULL;
- sound->playback_handle = NULL;
-
- /* versioning stuff, if there was a cache, then we enable caching: */
- if (sound->cache) {
- sound->flags |= SOUND_FLAGS_CACHING;
- sound->cache = NULL;
- }
-
- if (BLO_read_data_is_undo(reader)) {
- sound->tags |= SOUND_TAGS_WAVEFORM_NO_RELOAD;
- }
-
- sound->spinlock = MEM_mallocN(sizeof(SpinLock), "sound_spinlock");
- BLI_spin_init(sound->spinlock);
-
- /* clear waveform loading flag */
- sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
-
- BKE_packedfile_blend_read(reader, &sound->packedfile);
- BKE_packedfile_blend_read(reader, &sound->newpackedfile);
-}
-
-static void lib_link_sound(BlendLibReader *reader, bSound *sound)
-{
- BLO_read_id_address(
- reader, sound->id.lib, &sound->ipo); // XXX deprecated - old animation system
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Hair
- * \{ */
-
-static void lib_link_hair(BlendLibReader *reader, Hair *hair)
-{
- for (int a = 0; a < hair->totcol; a++) {
- BLO_read_id_address(reader, hair->id.lib, &hair->mat[a]);
- }
-}
-
-static void direct_link_hair(BlendDataReader *reader, Hair *hair)
-{
- BLO_read_data_address(reader, &hair->adt);
- BKE_animdata_blend_read_data(reader, hair->adt);
-
- /* Geometry */
- CustomData_blend_read(reader, &hair->pdata, hair->totpoint);
- CustomData_blend_read(reader, &hair->cdata, hair->totcurve);
- BKE_hair_update_customdata_pointers(hair);
-
- /* Materials */
- BLO_read_pointer_array(reader, (void **)&hair->mat);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Point Cloud
- * \{ */
-
-static void lib_link_pointcloud(BlendLibReader *reader, PointCloud *pointcloud)
-{
- for (int a = 0; a < pointcloud->totcol; a++) {
- BLO_read_id_address(reader, pointcloud->id.lib, &pointcloud->mat[a]);
- }
-}
-
-static void direct_link_pointcloud(BlendDataReader *reader, PointCloud *pointcloud)
-{
- BLO_read_data_address(reader, &pointcloud->adt);
- BKE_animdata_blend_read_data(reader, pointcloud->adt);
-
- /* Geometry */
- CustomData_blend_read(reader, &pointcloud->pdata, pointcloud->totpoint);
- BKE_pointcloud_update_customdata_pointers(pointcloud);
-
- /* Materials */
- BLO_read_pointer_array(reader, (void **)&pointcloud->mat);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Volume
- * \{ */
-
-static void lib_link_volume(BlendLibReader *reader, Volume *volume)
-{
- /* Needs to be done *after* cache pointers are restored (call to
- * `foreach_cache`/`blo_cache_storage_entry_restore_in_new`), easier for now to do it in
- * lib_link... */
- BKE_volume_init_grids(volume);
-
- for (int a = 0; a < volume->totcol; a++) {
- BLO_read_id_address(reader, volume->id.lib, &volume->mat[a]);
- }
-}
-
-static void direct_link_volume(BlendDataReader *reader, Volume *volume)
-{
- BLO_read_data_address(reader, &volume->adt);
- BKE_animdata_blend_read_data(reader, volume->adt);
-
- BKE_packedfile_blend_read(reader, &volume->packedfile);
- volume->runtime.frame = 0;
-
- /* materials */
- BLO_read_pointer_array(reader, (void **)&volume->mat);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Read ID: Simulation
- * \{ */
-
-static void lib_link_simulation(BlendLibReader *reader, Simulation *simulation)
-{
- LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
- BLO_read_id_address(reader, simulation->id.lib, &dependency->id);
- }
-}
-
-static void direct_link_simulation(BlendDataReader *reader, Simulation *simulation)
-{
- BLO_read_data_address(reader, &simulation->adt);
- BKE_animdata_blend_read_data(reader, simulation->adt);
-
- BLO_read_list(reader, &simulation->states);
- LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
- BLO_read_data_address(reader, &state->name);
- BLO_read_data_address(reader, &state->type);
- if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) {
- ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
- CustomData_blend_read(reader, &particle_state->attributes, particle_state->tot_particles);
- }
- }
-
- BLO_read_list(reader, &simulation->dependencies);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
/** \name Read Library Data Block
* \{ */
@@ -6634,45 +6341,21 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *
case ID_OB:
direct_link_object(&reader, (Object *)id);
break;
- case ID_TE:
- direct_link_texture(&reader, (Tex *)id);
- break;
case ID_IP:
direct_link_ipo(&reader, (Ipo *)id);
break;
case ID_LI:
direct_link_library(fd, (Library *)id, main);
break;
- case ID_SO:
- direct_link_sound(&reader, (bSound *)id);
- break;
case ID_GR:
direct_link_collection(&reader, (Collection *)id);
break;
case ID_PA:
direct_link_particlesettings(&reader, (ParticleSettings *)id);
break;
- case ID_GD:
- direct_link_gpencil(&reader, (bGPdata *)id);
- break;
- case ID_CF:
- direct_link_cachefile(&reader, (CacheFile *)id);
- break;
case ID_WS:
direct_link_workspace(&reader, (WorkSpace *)id, main);
break;
- case ID_HA:
- direct_link_hair(&reader, (Hair *)id);
- break;
- case ID_PT:
- direct_link_pointcloud(&reader, (PointCloud *)id);
- break;
- case ID_VO:
- direct_link_volume(&reader, (Volume *)id);
- break;
- case ID_SIM:
- direct_link_simulation(&reader, (Simulation *)id);
- break;
case ID_ME:
case ID_LT:
case ID_AC:
@@ -6696,6 +6379,14 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID *
case ID_AR:
case ID_LP:
case ID_KE:
+ case ID_TE:
+ case ID_GD:
+ case ID_HA:
+ case ID_PT:
+ case ID_VO:
+ case ID_SIM:
+ case ID_SO:
+ case ID_CF:
/* Do nothing. Handled by IDTypeInfo callback. */
break;
}
@@ -7315,8 +7006,8 @@ static void lib_link_all(FileData *fd, Main *bmain)
lib_link_object(&reader, (Object *)id);
break;
case ID_SCR:
- /* DO NOT skip screens here,
- * 3D viewport may contains pointers to other ID data (like bgpic)! See T41411. */
+ /* DO NOT skip screens here, 3D viewport may contains pointers
+ * to other ID data (like #View3D.ob_center)! See T41411. */
lib_link_screen(&reader, (bScreen *)id);
break;
case ID_PA:
@@ -7325,30 +7016,6 @@ static void lib_link_all(FileData *fd, Main *bmain)
case ID_GR:
lib_link_collection(&reader, (Collection *)id);
break;
- case ID_SO:
- lib_link_sound(&reader, (bSound *)id);
- break;
- case ID_CF:
- lib_link_cachefiles(&reader, (CacheFile *)id);
- break;
- case ID_HA:
- lib_link_hair(&reader, (Hair *)id);
- break;
- case ID_PT:
- lib_link_pointcloud(&reader, (PointCloud *)id);
- break;
- case ID_VO:
- lib_link_volume(&reader, (Volume *)id);
- break;
- case ID_TE:
- lib_link_texture(&reader, (Tex *)id);
- break;
- case ID_GD:
- lib_link_gpencil(&reader, (bGPdata *)id);
- break;
- case ID_SIM:
- lib_link_simulation(&reader, (Simulation *)id);
- break;
case ID_IP:
/* XXX deprecated... still needs to be maintained for version patches still. */
lib_link_ipo(&reader, (Ipo *)id);
@@ -7379,6 +7046,14 @@ static void lib_link_all(FileData *fd, Main *bmain)
case ID_AR:
case ID_LP:
case ID_KE:
+ case ID_TE:
+ case ID_GD:
+ case ID_HA:
+ case ID_PT:
+ case ID_VO:
+ case ID_SIM:
+ case ID_SO:
+ case ID_CF:
/* Do nothing. Handled by IDTypeInfo callback. */
break;
}
@@ -8064,12 +7739,6 @@ static void expand_collection(BlendExpander *expander, Collection *collection)
#endif
}
-static void expand_texture(BlendExpander *expander, Tex *tex)
-{
- BLO_expand(expander, tex->ima);
- BLO_expand(expander, tex->ipo); // XXX deprecated - old animation system
-}
-
/* callback function used to expand constraint ID-links */
static void expand_constraint_cb(bConstraint *UNUSED(con),
ID **idpoin,
@@ -8312,26 +7981,6 @@ static void expand_scene(BlendExpander *expander, Scene *sce)
}
}
-static void expand_cachefile(BlendExpander *UNUSED(expander), CacheFile *UNUSED(cache_file))
-{
-}
-
-static void expand_sound(BlendExpander *expander, bSound *snd)
-{
- BLO_expand(expander, snd->ipo); // XXX deprecated - old animation system
-}
-
-static void expand_gpencil(BlendExpander *expander, bGPdata *gpd)
-{
- LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- BLO_expand(expander, gpl->parent);
- }
-
- for (int a = 0; a < gpd->totcol; a++) {
- BLO_expand(expander, gpd->mat[a]);
- }
-}
-
static void expand_workspace(BlendExpander *expander, WorkSpace *workspace)
{
LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) {
@@ -8339,34 +7988,6 @@ static void expand_workspace(BlendExpander *expander, WorkSpace *workspace)
}
}
-static void expand_hair(BlendExpander *expander, Hair *hair)
-{
- for (int a = 0; a < hair->totcol; a++) {
- BLO_expand(expander, hair->mat[a]);
- }
-}
-
-static void expand_pointcloud(BlendExpander *expander, PointCloud *pointcloud)
-{
- for (int a = 0; a < pointcloud->totcol; a++) {
- BLO_expand(expander, pointcloud->mat[a]);
- }
-}
-
-static void expand_volume(BlendExpander *expander, Volume *volume)
-{
- for (int a = 0; a < volume->totcol; a++) {
- BLO_expand(expander, volume->mat[a]);
- }
-}
-
-static void expand_simulation(BlendExpander *expander, Simulation *simulation)
-{
- LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
- BLO_expand(expander, dependency->id);
- }
-}
-
/**
* Set the callback func used over all ID data found by \a BLO_expand_main func.
*
@@ -8416,12 +8037,6 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
case ID_SCE:
expand_scene(&expander, (Scene *)id);
break;
- case ID_TE:
- expand_texture(&expander, (Tex *)id);
- break;
- case ID_SO:
- expand_sound(&expander, (bSound *)id);
- break;
case ID_GR:
expand_collection(&expander, (Collection *)id);
break;
@@ -8431,27 +8046,9 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
case ID_PA:
expand_particlesettings(&expander, (ParticleSettings *)id);
break;
- case ID_GD:
- expand_gpencil(&expander, (bGPdata *)id);
- break;
- case ID_CF:
- expand_cachefile(&expander, (CacheFile *)id);
- break;
case ID_WS:
expand_workspace(&expander, (WorkSpace *)id);
break;
- case ID_HA:
- expand_hair(&expander, (Hair *)id);
- break;
- case ID_PT:
- expand_pointcloud(&expander, (PointCloud *)id);
- break;
- case ID_VO:
- expand_volume(&expander, (Volume *)id);
- break;
- case ID_SIM:
- expand_simulation(&expander, (Simulation *)id);
- break;
default:
break;
}
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index 5c1bf3b022a..876d122b082 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -234,6 +234,8 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
* the outliner's, and it's less disruptive to just copy them. */
copy_v4_v4_uchar(btheme->space_file.back, btheme->space_outliner.back);
copy_v4_v4_uchar(btheme->space_file.row_alternate, btheme->space_outliner.row_alternate);
+
+ FROM_DEFAULT_V4_UCHAR(space_image.grid);
}
#undef FROM_DEFAULT_V4_UCHAR
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index d4e3f4646d6..b3e937a29b2 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -95,9 +95,7 @@
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
-#include "DNA_brush_types.h"
#include "DNA_cachefile_types.h"
-#include "DNA_camera_types.h"
#include "DNA_cloth_types.h"
#include "DNA_collection_types.h"
#include "DNA_constraint_types.h"
@@ -106,45 +104,23 @@
#include "DNA_fileglobal_types.h"
#include "DNA_fluid_types.h"
#include "DNA_genfile.h"
-#include "DNA_gpencil_modifier_types.h"
-#include "DNA_gpencil_types.h"
-#include "DNA_hair_types.h"
-#include "DNA_key_types.h"
-#include "DNA_lattice_types.h"
-#include "DNA_layer_types.h"
-#include "DNA_light_types.h"
#include "DNA_lightprobe_types.h"
-#include "DNA_linestyle_types.h"
-#include "DNA_mask_types.h"
-#include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_meta_types.h"
#include "DNA_movieclip_types.h"
-#include "DNA_node_types.h"
#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
-#include "DNA_packedFile_types.h"
#include "DNA_particle_types.h"
#include "DNA_pointcache_types.h"
-#include "DNA_pointcloud_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_sdna_types.h"
#include "DNA_sequence_types.h"
#include "DNA_shader_fx_types.h"
-#include "DNA_simulation_types.h"
-#include "DNA_sound_types.h"
#include "DNA_space_types.h"
-#include "DNA_speaker_types.h"
-#include "DNA_text_types.h"
-#include "DNA_vfont_types.h"
#include "DNA_view3d_types.h"
-#include "DNA_volume_types.h"
#include "DNA_windowmanager_types.h"
#include "DNA_workspace_types.h"
-#include "DNA_world_types.h"
#include "BLI_bitmap.h"
#include "BLI_blenlib.h"
@@ -160,7 +136,6 @@
#include "BKE_collection.h"
#include "BKE_colortools.h"
#include "BKE_constraint.h"
-#include "BKE_curve.h"
#include "BKE_curveprofile.h"
#include "BKE_deform.h"
#include "BKE_fcurve.h"
@@ -1393,32 +1368,6 @@ static void write_object(BlendWriter *writer, Object *ob, const void *id_address
}
}
-static void write_texture(BlendWriter *writer, Tex *tex, const void *id_address)
-{
- if (tex->id.us > 0 || BLO_write_is_undo(writer)) {
- /* write LibData */
- BLO_write_id_struct(writer, Tex, id_address, &tex->id);
- BKE_id_blend_write(writer, &tex->id);
-
- if (tex->adt) {
- BKE_animdata_blend_write(writer, tex->adt);
- }
-
- /* direct data */
- if (tex->coba) {
- BLO_write_struct(writer, ColorBand, tex->coba);
- }
-
- /* nodetree is integral part of texture, no libdata */
- if (tex->nodetree) {
- BLO_write_struct(writer, bNodeTree, tex->nodetree);
- ntreeBlendWrite(writer, tex->nodetree);
- }
-
- BKE_previewimg_blend_write(writer, tex->preview);
- }
-}
-
static void write_collection_nolib(BlendWriter *writer, Collection *collection)
{
/* Shared function for collection data-blocks and scene master collection. */
@@ -1791,47 +1740,6 @@ static void write_scene(BlendWriter *writer, Scene *sce, const void *id_address)
BLI_assert(sce->layer_properties == NULL);
}
-static void write_gpencil(BlendWriter *writer, bGPdata *gpd, const void *id_address)
-{
- if (gpd->id.us > 0 || BLO_write_is_undo(writer)) {
- /* Clean up, important in undo case to reduce false detection of changed data-blocks. */
- /* XXX not sure why the whole run-time data is not cleared in reading code,
- * for now mimicking it here. */
- gpd->runtime.sbuffer = NULL;
- gpd->runtime.sbuffer_used = 0;
- gpd->runtime.sbuffer_size = 0;
- gpd->runtime.tot_cp_points = 0;
-
- /* write gpd data block to file */
- BLO_write_id_struct(writer, bGPdata, id_address, &gpd->id);
- BKE_id_blend_write(writer, &gpd->id);
-
- if (gpd->adt) {
- BKE_animdata_blend_write(writer, gpd->adt);
- }
-
- BLO_write_pointer_array(writer, gpd->totcol, gpd->mat);
-
- /* write grease-pencil layers to file */
- BLO_write_struct_list(writer, bGPDlayer, &gpd->layers);
- LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- /* Write mask list. */
- BLO_write_struct_list(writer, bGPDlayer_Mask, &gpl->mask_layers);
- /* write this layer's frames to file */
- BLO_write_struct_list(writer, bGPDframe, &gpl->frames);
- LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
- /* write strokes */
- BLO_write_struct_list(writer, bGPDstroke, &gpf->strokes);
- LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
- BLO_write_struct_array(writer, bGPDspoint, gps->totpoints, gps->points);
- BLO_write_struct_array(writer, bGPDtriangle, gps->tot_triangles, gps->triangles);
- BKE_defvert_blend_write(writer, gps->totpoints, gps->dvert);
- }
- }
- }
- }
-}
-
static void write_wm_xr_data(BlendWriter *writer, wmXrData *xr_data)
{
write_view3dshading(writer, &xr_data->session_settings.shading);
@@ -2122,40 +2030,6 @@ static void write_screen(BlendWriter *writer, bScreen *screen, const void *id_ad
}
}
-static void write_sound(BlendWriter *writer, bSound *sound, const void *id_address)
-{
- if (sound->id.us > 0 || BLO_write_is_undo(writer)) {
- /* Clean up, important in undo case to reduce false detection of changed datablocks. */
- sound->tags = 0;
- sound->handle = NULL;
- sound->playback_handle = NULL;
- sound->spinlock = NULL;
-
- /* write LibData */
- BLO_write_id_struct(writer, bSound, id_address, &sound->id);
- BKE_id_blend_write(writer, &sound->id);
-
- BKE_packedfile_blend_write(writer, sound->packedfile);
- }
-}
-
-static void write_cachefile(BlendWriter *writer, CacheFile *cache_file, const void *id_address)
-{
- if (cache_file->id.us > 0 || BLO_write_is_undo(writer)) {
- /* Clean up, important in undo case to reduce false detection of changed datablocks. */
- BLI_listbase_clear(&cache_file->object_paths);
- cache_file->handle = NULL;
- memset(cache_file->handle_filepath, 0, sizeof(cache_file->handle_filepath));
- cache_file->handle_readers = NULL;
-
- BLO_write_id_struct(writer, CacheFile, id_address, &cache_file->id);
-
- if (cache_file->adt) {
- BKE_animdata_blend_write(writer, cache_file->adt);
- }
- }
-}
-
static void write_workspace(BlendWriter *writer, WorkSpace *workspace, const void *id_address)
{
BLO_write_id_struct(writer, WorkSpace, id_address, &workspace->id);
@@ -2171,136 +2045,6 @@ static void write_workspace(BlendWriter *writer, WorkSpace *workspace, const voi
}
}
-static void write_hair(BlendWriter *writer, Hair *hair, const void *id_address)
-{
- if (hair->id.us > 0 || BLO_write_is_undo(writer)) {
- CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
- CustomDataLayer *clayers = NULL, clayers_buff[CD_TEMP_CHUNK_SIZE];
- CustomData_blend_write_prepare(&hair->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
- CustomData_blend_write_prepare(&hair->cdata, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff));
-
- /* Write LibData */
- BLO_write_id_struct(writer, Hair, id_address, &hair->id);
- BKE_id_blend_write(writer, &hair->id);
-
- /* Direct data */
- CustomData_blend_write(writer, &hair->pdata, players, hair->totpoint, CD_MASK_ALL, &hair->id);
- CustomData_blend_write(writer, &hair->cdata, clayers, hair->totcurve, CD_MASK_ALL, &hair->id);
-
- BLO_write_pointer_array(writer, hair->totcol, hair->mat);
- if (hair->adt) {
- BKE_animdata_blend_write(writer, hair->adt);
- }
-
- /* Remove temporary data. */
- if (players && players != players_buff) {
- MEM_freeN(players);
- }
- if (clayers && clayers != clayers_buff) {
- MEM_freeN(clayers);
- }
- }
-}
-
-static void write_pointcloud(BlendWriter *writer, PointCloud *pointcloud, const void *id_address)
-{
- if (pointcloud->id.us > 0 || BLO_write_is_undo(writer)) {
- CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
- CustomData_blend_write_prepare(
- &pointcloud->pdata, &players, players_buff, ARRAY_SIZE(players_buff));
-
- /* Write LibData */
- BLO_write_id_struct(writer, PointCloud, id_address, &pointcloud->id);
- BKE_id_blend_write(writer, &pointcloud->id);
-
- /* Direct data */
- CustomData_blend_write(
- writer, &pointcloud->pdata, players, pointcloud->totpoint, CD_MASK_ALL, &pointcloud->id);
-
- BLO_write_pointer_array(writer, pointcloud->totcol, pointcloud->mat);
- if (pointcloud->adt) {
- BKE_animdata_blend_write(writer, pointcloud->adt);
- }
-
- /* Remove temporary data. */
- if (players && players != players_buff) {
- MEM_freeN(players);
- }
- }
-}
-
-static void write_volume(BlendWriter *writer, Volume *volume, const void *id_address)
-{
- if (volume->id.us > 0 || BLO_write_is_undo(writer)) {
- /* Clean up, important in undo case to reduce false detection of changed datablocks. */
- volume->runtime.grids = 0;
-
- /* write LibData */
- BLO_write_id_struct(writer, Volume, id_address, &volume->id);
- BKE_id_blend_write(writer, &volume->id);
-
- /* direct data */
- BLO_write_pointer_array(writer, volume->totcol, volume->mat);
- if (volume->adt) {
- BKE_animdata_blend_write(writer, volume->adt);
- }
-
- BKE_packedfile_blend_write(writer, volume->packedfile);
- }
-}
-
-static void write_simulation(BlendWriter *writer, Simulation *simulation, const void *id_address)
-{
- if (simulation->id.us > 0 || BLO_write_is_undo(writer)) {
- BLO_write_id_struct(writer, Simulation, id_address, &simulation->id);
- BKE_id_blend_write(writer, &simulation->id);
-
- if (simulation->adt) {
- BKE_animdata_blend_write(writer, simulation->adt);
- }
-
- /* nodetree is integral part of simulation, no libdata */
- if (simulation->nodetree) {
- BLO_write_struct(writer, bNodeTree, simulation->nodetree);
- ntreeBlendWrite(writer, simulation->nodetree);
- }
-
- LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
- BLO_write_string(writer, state->name);
- BLO_write_string(writer, state->type);
- /* TODO: Decentralize this part. */
- if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_SIMULATION)) {
- ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
-
- CustomDataLayer *players = NULL, players_buff[CD_TEMP_CHUNK_SIZE];
- CustomData_blend_write_prepare(
- &particle_state->attributes, &players, players_buff, ARRAY_SIZE(players_buff));
-
- BLO_write_struct(writer, ParticleSimulationState, particle_state);
-
- CustomData_blend_write(writer,
- &particle_state->attributes,
- players,
- particle_state->tot_particles,
- CD_MASK_ALL,
- &simulation->id);
-
- /* Remove temporary data. */
- if (players && players != players_buff) {
- MEM_freeN(players);
- }
- }
- else if (STREQ(state->type, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER)) {
- ParticleMeshEmitterSimulationState *emitter_state = (ParticleMeshEmitterSimulationState *)
- state;
- BLO_write_struct(writer, ParticleMeshEmitterSimulationState, emitter_state);
- }
- }
-
- BLO_write_struct_list(writer, SimulationDependency, &simulation->dependencies);
- }
-}
-
/* Keep it last of write_foodata functions. */
static void write_libraries(WriteData *wd, Main *main)
{
@@ -2571,39 +2315,15 @@ static bool write_file_handle(Main *mainvar,
case ID_SCE:
write_scene(&writer, (Scene *)id_buffer, id);
break;
- case ID_SO:
- write_sound(&writer, (bSound *)id_buffer, id);
- break;
case ID_GR:
write_collection(&writer, (Collection *)id_buffer, id);
break;
case ID_OB:
write_object(&writer, (Object *)id_buffer, id);
break;
- case ID_TE:
- write_texture(&writer, (Tex *)id_buffer, id);
- break;
case ID_PA:
write_particlesettings(&writer, (ParticleSettings *)id_buffer, id);
break;
- case ID_GD:
- write_gpencil(&writer, (bGPdata *)id_buffer, id);
- break;
- case ID_CF:
- write_cachefile(&writer, (CacheFile *)id_buffer, id);
- break;
- case ID_HA:
- write_hair(&writer, (Hair *)id_buffer, id);
- break;
- case ID_PT:
- write_pointcloud(&writer, (PointCloud *)id_buffer, id);
- break;
- case ID_VO:
- write_volume(&writer, (Volume *)id_buffer, id);
- break;
- case ID_SIM:
- write_simulation(&writer, (Simulation *)id_buffer, id);
- break;
case ID_ME:
case ID_LT:
case ID_AC:
@@ -2627,6 +2347,14 @@ static bool write_file_handle(Main *mainvar,
case ID_AR:
case ID_LP:
case ID_KE:
+ case ID_TE:
+ case ID_GD:
+ case ID_HA:
+ case ID_PT:
+ case ID_VO:
+ case ID_SIM:
+ case ID_SO:
+ case ID_CF:
/* Do nothing, handled in IDTypeInfo callback. */
break;
case ID_LI:
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index 5f5d6baaba2..9199801d1a1 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -41,7 +41,7 @@
* \subsection bm_faces Faces
*
* Faces in BMesh are stored as a circular linked list of loops. Loops store per-face-vertex data
- * (amongst other things outlined later in this document), and define the face boundary.
+ * (among other things outlined later in this document), and define the face boundary.
* \subsection bm_loop The Loop
*
* Loops can be thought of as a *face-corner*, since faces don't reference verts or edges directly.
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
index e5dfee7d0cd..08f794d7eba 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
@@ -198,13 +198,13 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
const bNodeTree *bTree = context.getbNodeTree();
if (this->m_width == 0 || this->m_height == 0) {
return;
- } /// \note Break out... no pixels to calculate.
+ } /** \note Break out... no pixels to calculate. */
if (bTree->test_break && bTree->test_break(bTree->tbh)) {
return;
- } /// \note Early break out for blur and preview nodes.
+ } /** \note Early break out for blur and preview nodes. */
if (this->m_numberOfChunks == 0) {
return;
- } /// \note Early break out.
+ } /** \note Early break out. */
unsigned int chunkNumber;
this->m_executionStartTime = PIL_check_seconds_timer();
diff --git a/source/blender/compositor/intern/COM_NodeGraph.cpp b/source/blender/compositor/intern/COM_NodeGraph.cpp
index 01dd662ad11..fe680f61a90 100644
--- a/source/blender/compositor/intern/COM_NodeGraph.cpp
+++ b/source/blender/compositor/intern/COM_NodeGraph.cpp
@@ -184,7 +184,7 @@ NodeOutput *NodeGraph::find_output(const NodeRange &node_range, bNodeSocket *b_s
void NodeGraph::add_bNodeLink(const NodeRange &node_range, bNodeLink *b_nodelink)
{
- /// \note Ignore invalid links.
+ /** \note Ignore invalid links. */
if (!(b_nodelink->flag & NODE_LINK_VALID)) {
return;
}
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index 06929f0037e..570e1eeba20 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cpp
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp
@@ -44,26 +44,26 @@
# error COM_CURRENT_THREADING_MODEL No threading model selected
#endif
-/// \brief list of all CPUDevices. for every hardware thread an instance of CPUDevice is created
+/** \brief list of all CPUDevices. for every hardware thread an instance of CPUDevice is created */
static vector<CPUDevice *> g_cpudevices;
static ThreadLocal(CPUDevice *) g_thread_device;
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
-/// \brief list of all thread for every CPUDevice in cpudevices a thread exists
+/** \brief list of all thread for every CPUDevice in cpudevices a thread exists. */
static ListBase g_cputhreads;
static bool g_cpuInitialized = false;
-/// \brief all scheduled work for the cpu
+/** \brief all scheduled work for the cpu */
static ThreadQueue *g_cpuqueue;
static ThreadQueue *g_gpuqueue;
# ifdef COM_OPENCL_ENABLED
static cl_context g_context;
static cl_program g_program;
-/// \brief list of all OpenCLDevices. for every OpenCL GPU device an instance of OpenCLDevice is
-/// created
+/** \brief list of all OpenCLDevices. for every OpenCL GPU device an instance of OpenCLDevice is
+ * created. */
static vector<OpenCLDevice *> g_gpudevices;
-/// \brief list of all thread for every GPUDevice in cpudevices a thread exists
+/** \brief list of all thread for every GPUDevice in cpudevices a thread exists. */
static ListBase g_gputhreads;
-/// \brief all scheduled work for the gpu
+/** \brief all scheduled work for the GPU. */
static bool g_openclActive = false;
static bool g_openclInitialized = false;
# endif
diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp
index 3dbd3773247..c178722a23f 100644
--- a/source/blender/compositor/nodes/COM_ImageNode.cpp
+++ b/source/blender/compositor/nodes/COM_ImageNode.cpp
@@ -72,7 +72,7 @@ NodeOperation *ImageNode::doMultilayerCheck(NodeConverter &converter,
void ImageNode::convertToOperations(NodeConverter &converter,
const CompositorContext &context) const
{
- /// Image output
+ /** Image output */
NodeOutput *outputImage = this->getOutputSocket(0);
bNode *editorNode = this->getbNode();
Image *image = (Image *)editorNode->id;
diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp
index 70aaab560cd..99cc9f5dd01 100644
--- a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp
+++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp
@@ -41,7 +41,7 @@ void ReadBufferOperation::determineResolution(unsigned int resolution[2],
operation->determineResolution(resolution, preferredResolution);
operation->setResolution(resolution);
- /// \todo: may not occur!, but does with blur node
+ /** \todo: may not occur!, but does with blur node */
if (this->m_memoryProxy->getExecutor()) {
this->m_memoryProxy->getExecutor()->setResolution(resolution);
}
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp
index 3d5d50e1c7f..e1d891559a7 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.cpp
+++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp
@@ -190,7 +190,7 @@ void ViewerOperation::updateImage(rcti *rect)
rect->ymin,
rect->xmax,
rect->ymax);
-
+ this->m_image->gpuflag |= IMA_GPU_REFRESH;
this->updateDraw();
}
diff --git a/source/blender/depsgraph/intern/depsgraph_physics.cc b/source/blender/depsgraph/intern/depsgraph_physics.cc
index bc73700e1ba..0b8203ab05f 100644
--- a/source/blender/depsgraph/intern/depsgraph_physics.cc
+++ b/source/blender/depsgraph/intern/depsgraph_physics.cc
@@ -96,7 +96,7 @@ ListBase *DEG_get_collision_relations(const Depsgraph *graph,
if (hash == nullptr) {
return nullptr;
}
- /* Note: nullptr is a valid loolup key here as it means that the relation is not bound to a
+ /* Note: nullptr is a valid lookup key here as it means that the relation is not bound to a
* specific collection. */
ID *collection_orig = DEG_get_original_id(object_id_safe(collection));
return hash->lookup_default(collection_orig, nullptr);
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 8aea2f8e969..1344d390871 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -44,10 +44,6 @@ set(INC
../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
intern/draw_cache.c
intern/draw_cache_extract_mesh.c
@@ -77,6 +73,8 @@ set(SRC
intern/draw_select_buffer.c
intern/draw_view.c
engines/basic/basic_engine.c
+ engines/image/image_engine.c
+ engines/image/image_shader.c
engines/eevee/eevee_bloom.c
engines/eevee/eevee_data.c
engines/eevee/eevee_depth_of_field.c
@@ -132,6 +130,7 @@ set(SRC
engines/overlay/overlay_edit_curve.c
engines/overlay/overlay_edit_mesh.c
engines/overlay/overlay_edit_text.c
+ engines/overlay/overlay_edit_uv.c
engines/overlay/overlay_engine.c
engines/overlay/overlay_extra.c
engines/overlay/overlay_facing.c
@@ -319,6 +318,7 @@ data_to_c_simple(engines/basic/shaders/conservative_depth_geom.glsl SRC)
data_to_c_simple(engines/basic/shaders/depth_vert.glsl SRC)
data_to_c_simple(engines/basic/shaders/depth_frag.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/common_overlay_lib.glsl SRC)
data_to_c_simple(engines/overlay/shaders/antialiasing_frag.glsl SRC)
data_to_c_simple(engines/overlay/shaders/antialiasing_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/armature_dof_vert.glsl SRC)
@@ -362,6 +362,15 @@ data_to_c_simple(engines/overlay/shaders/edit_mesh_skin_root_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/edit_mesh_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/edit_particle_strand_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/edit_particle_point_vert.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/edit_uv_edges_vert.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/edit_uv_edges_geom.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/edit_uv_edges_frag.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/edit_uv_verts_vert.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/edit_uv_verts_frag.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/edit_uv_faces_vert.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/edit_uv_face_dots_vert.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/edit_uv_stretching_vert.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/edit_uv_tiled_image_borders_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/extra_frag.glsl SRC)
data_to_c_simple(engines/overlay/shaders/extra_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/extra_groundline_vert.glsl SRC)
@@ -402,6 +411,9 @@ data_to_c_simple(engines/overlay/shaders/wireframe_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/wireframe_frag.glsl SRC)
data_to_c_simple(engines/overlay/shaders/xray_fade_frag.glsl SRC)
+data_to_c_simple(engines/image/shaders/engine_image_frag.glsl SRC)
+data_to_c_simple(engines/image/shaders/engine_image_vert.glsl SRC)
+
list(APPEND INC
)
@@ -426,7 +438,6 @@ if(WITH_GTESTS)
endif()
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_draw "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 6db3bb39643..ca5c2c94b40 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -99,6 +99,10 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph,
const bool do_color_management,
struct GPUOffScreen *ofs,
struct GPUViewport *viewport);
+void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph,
+ struct ARegion *region,
+ struct GPUViewport *viewport,
+ const struct bContext *evil_C);
void DRW_draw_select_loop(struct Depsgraph *depsgraph,
struct ARegion *region,
struct View3D *v3d,
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 8216d2545ac..e731ed071b2 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -84,9 +84,7 @@ extern struct DrawEngineType draw_engine_eevee_type;
#define EEVEE_PROBE_MAX min_ii(MAX_PROBE, GPU_max_texture_layers() / 6)
#define EEVEE_VELOCITY_TILE_SIZE 32
-#define USE_VOLUME_OPTI \
- (GLEW_ARB_shader_image_load_store && GLEW_ARB_shading_language_420pack && \
- !GPU_crappy_amd_driver())
+#define USE_VOLUME_OPTI (GPU_shader_image_load_store_support())
#define SWAP_DOUBLE_BUFFERS() \
{ \
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index 69b916244b5..93701887b51 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -601,6 +601,10 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
+ if (USE_VOLUME_OPTI) {
+ DRW_shgroup_uniform_image_ref(grp, "finalScattering_img", &txl->volume_scatter_history);
+ DRW_shgroup_uniform_image_ref(grp, "finalTransmittance_img", &txl->volume_transmit_history);
+ }
DRW_shgroup_call_procedural_triangles(
grp, NULL, USE_VOLUME_OPTI ? 1 : common_data->vol_tex_size[2]);
@@ -610,6 +614,7 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
+ DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
@@ -714,15 +719,7 @@ void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_draw_pass(psl->volumetric_scatter_ps);
if (USE_VOLUME_OPTI) {
- int tex_scatter = GPU_texture_opengl_bindcode(txl->volume_scatter_history);
- int tex_transmit = GPU_texture_opengl_bindcode(txl->volume_transmit_history);
- /* TODO(fclem) Encapsulate these GL calls into DRWManager. */
- glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
- /* Subtlety here! we need to tell the GL that the texture is layered (GL_TRUE)
- * in order to bind the full 3D texture and not just a 2D slice. */
- glBindImageTexture(0, tex_scatter, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R11F_G11F_B10F);
- glBindImageTexture(1, tex_transmit, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R11F_G11F_B10F);
-
+ /* Avoid feedback loop assert. */
GPU_framebuffer_bind(fbl->volumetric_fb);
}
else {
@@ -731,13 +728,6 @@ void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_draw_pass(psl->volumetric_integration_ps);
- if (USE_VOLUME_OPTI) {
- glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
-
- glBindImageTexture(0, 0, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R11F_G11F_B10F);
- glBindImageTexture(1, 0, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R11F_G11F_B10F);
- }
-
SWAP(struct GPUFrameBuffer *, fbl->volumetric_scat_fb, fbl->volumetric_integ_fb);
SWAP(GPUTexture *, txl->volume_scatter, txl->volume_scatter_history);
SWAP(GPUTexture *, txl->volume_transmit, txl->volume_transmit_history);
@@ -763,6 +753,10 @@ void EEVEE_volumes_resolve(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
e_data.depth_src = dtxl->depth;
+ if (USE_VOLUME_OPTI) {
+ GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
+ }
+
/* Apply for opaque geometry. */
GPU_framebuffer_bind(fbl->main_color_fb);
DRW_draw_pass(psl->volumetric_resolve_ps);
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
index f4276bd61bd..12b7d8acbea 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
@@ -11,8 +11,8 @@ uniform sampler3D volumeScattering; /* Result of the scatter step */
uniform sampler3D volumeExtinction;
#ifdef USE_VOLUME_OPTI
-uniform layout(binding = 0, r11f_g11f_b10f) writeonly restrict image3D finalScattering_img;
-uniform layout(binding = 1, r11f_g11f_b10f) writeonly restrict image3D finalTransmittance_img;
+uniform layout(r11f_g11f_b10f) writeonly restrict image3D finalScattering_img;
+uniform layout(r11f_g11f_b10f) writeonly restrict image3D finalTransmittance_img;
vec3 finalScattering;
vec3 finalTransmittance;
diff --git a/source/blender/draw/engines/image/image_engine.c b/source/blender/draw/engines/image/image_engine.c
new file mode 100644
index 00000000000..9f1278b473b
--- /dev/null
+++ b/source/blender/draw/engines/image/image_engine.c
@@ -0,0 +1,304 @@
+/*
+ * 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 draw_editors
+ *
+ * Draw engine to draw the Image/UV editor
+ */
+
+#include "DRW_render.h"
+
+#include "BKE_image.h"
+#include "BKE_object.h"
+
+#include "DNA_camera_types.h"
+
+#include "IMB_imbuf_types.h"
+
+#include "ED_image.h"
+
+#include "GPU_batch.h"
+
+#include "image_engine.h"
+#include "image_private.h"
+
+#define SIMA_DRAW_FLAG_SHOW_ALPHA (1 << 0)
+#define SIMA_DRAW_FLAG_APPLY_ALPHA (1 << 1)
+#define SIMA_DRAW_FLAG_SHUFFLING (1 << 2)
+#define SIMA_DRAW_FLAG_DEPTH (1 << 3)
+#define SIMA_DRAW_FLAG_TILED (1 << 4)
+#define SIMA_DRAW_FLAG_DO_REPEAT (1 << 5)
+
+static void image_cache_image_add(DRWShadingGroup *grp, Image *image)
+{
+ const bool is_tiled_texture = image && image->source == IMA_SRC_TILED;
+ float obmat[4][4];
+ unit_m4(obmat);
+
+ GPUBatch *geom = DRW_cache_quad_get();
+
+ if (is_tiled_texture) {
+ LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
+ const int tile_x = ((tile->tile_number - 1001) % 10);
+ const int tile_y = ((tile->tile_number - 1001) / 10);
+ obmat[3][1] = (float)tile_y;
+ obmat[3][0] = (float)tile_x;
+ DRW_shgroup_call_obmat(grp, geom, obmat);
+ }
+ }
+ else {
+ DRW_shgroup_call_obmat(grp, geom, obmat);
+ }
+}
+
+static void image_gpu_texture_get(Image *image,
+ ImageUser *iuser,
+ ImBuf *ibuf,
+ GPUTexture **r_gpu_texture,
+ bool *r_owns_texture,
+ GPUTexture **r_tex_tile_data)
+{
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
+
+ if (image) {
+ if (BKE_image_is_multilayer(image)) {
+ /* update multiindex and pass for the current eye */
+ BKE_image_multilayer_index(image->rr, &sima->iuser);
+ }
+ else {
+ BKE_image_multiview_index(image, &sima->iuser);
+ }
+
+ if (ibuf) {
+ if (sima->flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1))) {
+ if (ibuf->zbuf) {
+ BLI_assert(!"Integer based depth buffers not supported");
+ }
+ else if (ibuf->zbuf_float) {
+ *r_gpu_texture = GPU_texture_create_2d(
+ __func__, ibuf->x, ibuf->y, 0, GPU_R16F, ibuf->zbuf_float);
+ *r_owns_texture = true;
+ }
+ else if (ibuf->rect_float && ibuf->channels == 1) {
+ *r_gpu_texture = GPU_texture_create_2d(
+ __func__, ibuf->x, ibuf->y, 0, GPU_R16F, ibuf->rect_float);
+ *r_owns_texture = true;
+ }
+ }
+ else if (image->source == IMA_SRC_TILED) {
+ *r_gpu_texture = BKE_image_get_gpu_tiles(image, iuser, ibuf);
+ *r_tex_tile_data = BKE_image_get_gpu_tilemap(image, iuser, NULL);
+ *r_owns_texture = false;
+ }
+ else {
+ *r_gpu_texture = BKE_image_get_gpu_texture(image, iuser, ibuf);
+ *r_owns_texture = false;
+ }
+ }
+ }
+}
+
+static void image_cache_image(IMAGE_Data *vedata, Image *image, ImageUser *iuser, ImBuf *ibuf)
+{
+ IMAGE_PassList *psl = vedata->psl;
+ IMAGE_StorageList *stl = vedata->stl;
+ IMAGE_PrivateData *pd = stl->pd;
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const Scene *scene = draw_ctx->scene;
+ SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
+
+ GPUTexture *tex_tile_data = NULL;
+ image_gpu_texture_get(image, iuser, ibuf, &pd->texture, &pd->owns_texture, &tex_tile_data);
+
+ if (pd->texture) {
+ static float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ static float shuffle[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ static float far_near[2] = {100.0f, 0.0f};
+
+ if (scene->camera && scene->camera->type == OB_CAMERA) {
+ far_near[1] = ((Camera *)scene->camera->data)->clip_start;
+ far_near[0] = ((Camera *)scene->camera->data)->clip_end;
+ }
+
+ const bool use_premul_alpha = image->alpha_mode == IMA_ALPHA_PREMUL;
+ const bool is_tiled_texture = tex_tile_data != NULL;
+ const bool do_repeat = (!is_tiled_texture) && ((sima->flag & SI_DRAW_TILE) != 0);
+ const bool is_zoom_out = sima->zoom < 1.0f;
+
+ /* use interpolation filtering when zooming out */
+ eGPUSamplerState state = 0;
+ SET_FLAG_FROM_TEST(state, is_zoom_out, GPU_SAMPLER_FILTER);
+
+ int draw_flags = 0;
+ SET_FLAG_FROM_TEST(draw_flags, do_repeat, SIMA_DRAW_FLAG_DO_REPEAT);
+
+ if ((sima->flag & SI_USE_ALPHA) != 0) {
+ /* Show RGBA */
+ draw_flags |= SIMA_DRAW_FLAG_SHOW_ALPHA | SIMA_DRAW_FLAG_APPLY_ALPHA;
+ }
+ else if ((sima->flag & SI_SHOW_ALPHA) != 0) {
+ draw_flags |= SIMA_DRAW_FLAG_SHUFFLING;
+ copy_v4_fl4(shuffle, 0.0f, 0.0f, 0.0f, 1.0f);
+ }
+ else if ((sima->flag & SI_SHOW_ZBUF) != 0) {
+ draw_flags |= SIMA_DRAW_FLAG_DEPTH | SIMA_DRAW_FLAG_SHUFFLING;
+ copy_v4_fl4(shuffle, 1.0f, 0.0f, 0.0f, 0.0f);
+ }
+ else if ((sima->flag & SI_SHOW_R) != 0) {
+ draw_flags |= SIMA_DRAW_FLAG_APPLY_ALPHA | SIMA_DRAW_FLAG_SHUFFLING;
+ copy_v4_fl4(shuffle, 1.0f, 0.0f, 0.0f, 0.0f);
+ }
+ else if ((sima->flag & SI_SHOW_G) != 0) {
+ draw_flags |= SIMA_DRAW_FLAG_APPLY_ALPHA | SIMA_DRAW_FLAG_SHUFFLING;
+ copy_v4_fl4(shuffle, 0.0f, 1.0f, 0.0f, 0.0f);
+ }
+ else if ((sima->flag & SI_SHOW_B) != 0) {
+ draw_flags |= SIMA_DRAW_FLAG_APPLY_ALPHA | SIMA_DRAW_FLAG_SHUFFLING;
+ copy_v4_fl4(shuffle, 0.0f, 0.0f, 1.0f, 0.0f);
+ }
+ else /* RGB */ {
+ draw_flags |= SIMA_DRAW_FLAG_APPLY_ALPHA;
+ }
+
+ GPUShader *shader = IMAGE_shader_image_get();
+ DRWShadingGroup *shgrp = DRW_shgroup_create(shader, psl->image_pass);
+ if (tex_tile_data != NULL) {
+ draw_flags |= SIMA_DRAW_FLAG_TILED;
+ DRW_shgroup_uniform_texture_ex(shgrp, "imageTileArray", pd->texture, state);
+ DRW_shgroup_uniform_texture(shgrp, "imageTileData", tex_tile_data);
+ }
+ else {
+ DRW_shgroup_uniform_texture_ex(shgrp, "imageTexture", pd->texture, state);
+ }
+ DRW_shgroup_uniform_vec2_copy(shgrp, "farNearDistances", far_near);
+ DRW_shgroup_uniform_vec4_copy(shgrp, "color", color);
+ DRW_shgroup_uniform_vec4_copy(shgrp, "shuffle", shuffle);
+ DRW_shgroup_uniform_int_copy(shgrp, "drawFlags", draw_flags);
+ DRW_shgroup_uniform_bool_copy(shgrp, "imgPremultiplied", use_premul_alpha);
+ image_cache_image_add(shgrp, image);
+ }
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Engine Callbacks
+ * \{ */
+static void IMAGE_engine_init(void *ved)
+{
+ IMAGE_shader_library_ensure();
+ IMAGE_Data *vedata = (IMAGE_Data *)ved;
+ IMAGE_StorageList *stl = vedata->stl;
+ if (!stl->pd) {
+ stl->pd = MEM_callocN(sizeof(IMAGE_PrivateData), __func__);
+ }
+ IMAGE_PrivateData *pd = stl->pd;
+
+ pd->ibuf = NULL;
+ pd->lock = NULL;
+ pd->texture = NULL;
+}
+
+static void IMAGE_cache_init(void *ved)
+{
+ IMAGE_Data *vedata = (IMAGE_Data *)ved;
+ IMAGE_StorageList *stl = vedata->stl;
+ IMAGE_PrivateData *pd = stl->pd;
+ IMAGE_PassList *psl = vedata->psl;
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
+
+ {
+ /* Write depth is needed for background overlay rendering. Near depth is used for
+ * transparency checker and Far depth is used for indicating the image size. */
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS |
+ DRW_STATE_BLEND_ALPHA_PREMUL;
+ psl->image_pass = DRW_pass_create("Image", state);
+ }
+
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ GPU_framebuffer_bind(dfbl->default_fb);
+ static float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ GPU_framebuffer_clear_color_depth(dfbl->default_fb, clear_col, 1.0);
+
+ {
+ Image *image = ED_space_image(sima);
+ ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &pd->lock, 0);
+ image_cache_image(vedata, image, &sima->iuser, ibuf);
+ pd->ibuf = ibuf;
+ }
+}
+
+static void IMAGE_cache_populate(void *UNUSED(vedata), Object *UNUSED(ob))
+{
+ /* Function intentional left empty. `cache_populate` is required to be implemented. */
+}
+
+static void image_draw_finish(IMAGE_Data *ved)
+{
+ IMAGE_Data *vedata = (IMAGE_Data *)ved;
+ IMAGE_StorageList *stl = vedata->stl;
+ IMAGE_PrivateData *pd = stl->pd;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
+
+ ED_space_image_release_buffer(sima, pd->ibuf, pd->lock);
+
+ if (pd->texture && pd->owns_texture) {
+ GPU_texture_free(pd->texture);
+ pd->owns_texture = false;
+ }
+ pd->texture = NULL;
+}
+
+static void IMAGE_draw_scene(void *ved)
+{
+ IMAGE_Data *vedata = (IMAGE_Data *)ved;
+ IMAGE_PassList *psl = vedata->psl;
+
+ DRW_draw_pass(psl->image_pass);
+
+ image_draw_finish(vedata);
+}
+
+static void IMAGE_engine_free(void)
+{
+ IMAGE_shader_free();
+}
+
+/* \} */
+static const DrawEngineDataSize IMAGE_data_size = DRW_VIEWPORT_DATA_SIZE(IMAGE_Data);
+
+DrawEngineType draw_engine_image_type = {
+ NULL, /* next */
+ NULL, /* prev */
+ N_("UV/Image"), /* idname */
+ &IMAGE_data_size, /* vedata_size */
+ &IMAGE_engine_init, /* engine_init */
+ &IMAGE_engine_free, /* engine_free */
+ &IMAGE_cache_init, /* cache_init */
+ &IMAGE_cache_populate, /* cache_populate */
+ NULL, /* cache_finish */
+ &IMAGE_draw_scene, /* draw_scene */
+ NULL, /* view_update */
+ NULL, /* id_update */
+ NULL, /* render_to_image */
+};
diff --git a/source/blender/gpu/GPU_debug.h b/source/blender/draw/engines/image/image_engine.h
index 09dc02c0fc6..0098d863ef9 100644
--- a/source/blender/gpu/GPU_debug.h
+++ b/source/blender/draw/engines/image/image_engine.h
@@ -13,23 +13,13 @@
* 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) 2005 Blender Foundation.
- * All rights reserved.
+ * Copyright 2020, Blender Foundation.
*/
/** \file
- * \ingroup gpu
+ * \ingroup draw_editors
*/
#pragma once
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* prints something if debug mode is active only */
-void GPU_print_error_debug(const char *str);
-
-#ifdef __cplusplus
-}
-#endif
+extern DrawEngineType draw_engine_image_type;
diff --git a/source/blender/draw/engines/image/image_private.h b/source/blender/draw/engines/image/image_private.h
new file mode 100644
index 00000000000..d11d868d4d2
--- /dev/null
+++ b/source/blender/draw/engines/image/image_private.h
@@ -0,0 +1,69 @@
+/*
+ * 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 draw_engine
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward declarations */
+struct rcti;
+struct GPUBatch;
+struct Image;
+struct ImBuf;
+struct GPUTexture;
+
+/* *********** LISTS *********** */
+
+/* GPUViewport.storage
+ * Is freed everytime the viewport engine changes */
+typedef struct IMAGE_PassList {
+ DRWPass *image_pass;
+} IMAGE_PassList;
+
+typedef struct IMAGE_PrivateData {
+ void *lock;
+ struct ImBuf *ibuf;
+
+ struct GPUTexture *texture;
+ bool owns_texture;
+} IMAGE_PrivateData;
+
+typedef struct IMAGE_StorageList {
+ IMAGE_PrivateData *pd;
+} IMAGE_StorageList;
+
+typedef struct IMAGE_Data {
+ void *engine_type;
+ DRWViewportEmptyList *fbl;
+ DRWViewportEmptyList *txl;
+ IMAGE_PassList *psl;
+ IMAGE_StorageList *stl;
+} IMAGE_Data;
+
+/* image_shader.c */
+GPUShader *IMAGE_shader_image_get(void);
+void IMAGE_shader_library_ensure(void);
+void IMAGE_shader_free(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/draw/engines/image/image_shader.c b/source/blender/draw/engines/image/image_shader.c
new file mode 100644
index 00000000000..433c79e20cf
--- /dev/null
+++ b/source/blender/draw/engines/image/image_shader.c
@@ -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.
+ *
+ * Copyright 2020, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup draw_engine
+ */
+
+#include "DRW_render.h"
+
+#include "BLI_dynstr.h"
+
+#include "GPU_batch.h"
+
+#include "image_engine.h"
+#include "image_private.h"
+
+extern char datatoc_common_colormanagement_lib_glsl[];
+extern char datatoc_common_globals_lib_glsl[];
+extern char datatoc_common_view_lib_glsl[];
+
+extern char datatoc_engine_image_frag_glsl[];
+extern char datatoc_engine_image_vert_glsl[];
+
+typedef struct IMAGE_Shaders {
+ GPUShader *image_sh;
+} IMAGE_Shaders;
+
+static struct {
+ IMAGE_Shaders shaders;
+ DRWShaderLibrary *lib;
+} e_data = {0}; /* Engine data */
+
+void IMAGE_shader_library_ensure(void)
+{
+ if (e_data.lib == NULL) {
+ e_data.lib = DRW_shader_library_create();
+ /* NOTE: Theses needs to be ordered by dependencies. */
+ DRW_SHADER_LIB_ADD(e_data.lib, common_colormanagement_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_globals_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
+ }
+}
+
+GPUShader *IMAGE_shader_image_get(void)
+{
+ IMAGE_Shaders *sh_data = &e_data.shaders;
+ if (!sh_data->image_sh) {
+ sh_data->image_sh = DRW_shader_create_with_shaderlib(
+ datatoc_engine_image_vert_glsl, NULL, datatoc_engine_image_frag_glsl, e_data.lib, NULL);
+ }
+ return sh_data->image_sh;
+}
+
+void IMAGE_shader_free(void)
+{
+ GPUShader **sh_data_as_array = (GPUShader **)&e_data.shaders;
+ for (int i = 0; i < (sizeof(IMAGE_Shaders) / sizeof(GPUShader *)); i++) {
+ DRW_SHADER_FREE_SAFE(sh_data_as_array[i]);
+ }
+
+ DRW_SHADER_LIB_FREE_SAFE(e_data.lib);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/image/shaders/engine_image_frag.glsl b/source/blender/draw/engines/image/shaders/engine_image_frag.glsl
new file mode 100644
index 00000000000..5c5d9362dfc
--- /dev/null
+++ b/source/blender/draw/engines/image/shaders/engine_image_frag.glsl
@@ -0,0 +1,91 @@
+#pragma BLENDER_REQUIRE(common_colormanagement_lib.glsl)
+
+/* Keep in sync with image_engine.c */
+#define SIMA_DRAW_FLAG_SHOW_ALPHA (1 << 0)
+#define SIMA_DRAW_FLAG_APPLY_ALPHA (1 << 1)
+#define SIMA_DRAW_FLAG_SHUFFLING (1 << 2)
+#define SIMA_DRAW_FLAG_DEPTH (1 << 3)
+#define SIMA_DRAW_FLAG_TILED (1 << 4)
+#define SIMA_DRAW_FLAG_DO_REPEAT (1 << 5)
+
+uniform sampler2DArray imageTileArray;
+uniform sampler1DArray imageTileData;
+uniform sampler2D imageTexture;
+
+uniform bool imgPremultiplied;
+uniform int drawFlags;
+uniform vec2 farNearDistances;
+uniform vec4 color;
+uniform vec4 shuffle;
+
+#define FAR_DISTANCE farNearDistances.x
+#define NEAR_DISTANCE farNearDistances.y
+
+in vec2 uvs;
+
+out vec4 fragColor;
+
+/* TODO(fclem) deduplicate code. */
+bool node_tex_tile_lookup(inout vec3 co, sampler2DArray ima, sampler1DArray map)
+{
+ vec2 tile_pos = floor(co.xy);
+
+ if (tile_pos.x < 0 || tile_pos.y < 0 || tile_pos.x >= 10) {
+ return false;
+ }
+
+ float tile = 10.0 * tile_pos.y + tile_pos.x;
+ if (tile >= textureSize(map, 0).x) {
+ return false;
+ }
+
+ /* Fetch tile information. */
+ float tile_layer = texelFetch(map, ivec2(tile, 0), 0).x;
+ if (tile_layer < 0.0) {
+ return false;
+ }
+
+ vec4 tile_info = texelFetch(map, ivec2(tile, 1), 0);
+
+ co = vec3(((co.xy - tile_pos) * tile_info.zw) + tile_info.xy, tile_layer);
+ return true;
+}
+
+void main()
+{
+ vec4 tex_color;
+ /* Read texture */
+ if ((drawFlags & SIMA_DRAW_FLAG_TILED) != 0) {
+ vec3 co = vec3(uvs, 0.0);
+ if (node_tex_tile_lookup(co, imageTileArray, imageTileData)) {
+ tex_color = texture(imageTileArray, co);
+ }
+ else {
+ tex_color = vec4(1.0, 0.0, 1.0, 1.0);
+ }
+ }
+ else {
+ vec2 uvs_clamped = ((drawFlags & SIMA_DRAW_FLAG_DO_REPEAT) != 0) ?
+ fract(uvs) :
+ clamp(uvs, vec2(0.0), vec2(1.0));
+ tex_color = texture(imageTexture, uvs_clamped);
+ }
+
+ if ((drawFlags & SIMA_DRAW_FLAG_APPLY_ALPHA) != 0) {
+ if (!imgPremultiplied && tex_color.a != 0.0 && tex_color.a != 1.0) {
+ tex_color.rgb *= tex_color.a;
+ }
+ }
+ if ((drawFlags & SIMA_DRAW_FLAG_DEPTH) != 0) {
+ tex_color = smoothstep(FAR_DISTANCE, NEAR_DISTANCE, tex_color);
+ }
+
+ if ((drawFlags & SIMA_DRAW_FLAG_SHUFFLING) != 0) {
+ tex_color = color * dot(tex_color, shuffle);
+ }
+ if ((drawFlags & SIMA_DRAW_FLAG_SHOW_ALPHA) == 0) {
+ tex_color.a = 1.0;
+ }
+
+ fragColor = tex_color;
+}
diff --git a/source/blender/draw/engines/image/shaders/engine_image_vert.glsl b/source/blender/draw/engines/image/shaders/engine_image_vert.glsl
new file mode 100644
index 00000000000..3f1fb154d44
--- /dev/null
+++ b/source/blender/draw/engines/image/shaders/engine_image_vert.glsl
@@ -0,0 +1,31 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+#define SIMA_DRAW_FLAG_DO_REPEAT (1 << 5)
+
+uniform int drawFlags;
+
+in vec3 pos;
+out vec2 uvs;
+
+void main()
+{
+ /* `pos` contains the coordinates of a quad (-1..1). but we need the coordinates of an image
+ * plane (0..1) */
+ vec3 image_pos = pos * 0.5 + 0.5;
+
+ if ((drawFlags & SIMA_DRAW_FLAG_DO_REPEAT) != 0) {
+ gl_Position = vec4(pos.xy, 0.0, 1.0);
+ uvs = point_view_to_object(image_pos).xy;
+ }
+ else {
+ vec3 world_pos = point_object_to_world(image_pos);
+ vec4 position = point_world_to_ndc(world_pos);
+ /* Move drawn pixels to the front. In the overlay engine the depth is used
+ * to detect if a transparency texture or the background color should be drawn.
+ * Vertices are between 0.0 and 0.2, Edges between 0.2 and 0.4
+ * actual pixels are at 0.75, 1.0 is used for the background. */
+ position.z = 0.75;
+ gl_Position = position;
+ uvs = world_pos.xy;
+ }
+}
diff --git a/source/blender/draw/engines/overlay/overlay_background.c b/source/blender/draw/engines/overlay/overlay_background.c
index f52ae691a35..cb09d916a0f 100644
--- a/source/blender/draw/engines/overlay/overlay_background.c
+++ b/source/blender/draw/engines/overlay/overlay_background.c
@@ -31,6 +31,7 @@
#define BG_GRADIENT 1
#define BG_CHECKER 2
#define BG_RADIAL 3
+#define BG_SOLID_CHECKER 4
void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
{
@@ -40,7 +41,7 @@ void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene = draw_ctx->scene;
const RegionView3D *rv3d = draw_ctx->rv3d;
- const BoundBox *bb = rv3d->clipbb;
+ const BoundBox *bb = rv3d ? rv3d->clipbb : NULL;
const View3D *v3d = draw_ctx->v3d;
bool draw_clipping_bounds = (pd->clipping_state != 0);
@@ -50,9 +51,11 @@ void OVERLAY_background_cache_init(OVERLAY_Data *vedata)
if (DRW_state_is_opengl_render() && !DRW_state_draw_background()) {
background_type = BG_SOLID;
- zero_v3(color_override);
color_override[3] = 1.0f;
}
+ else if (pd->is_image_editor) {
+ background_type = BG_SOLID_CHECKER;
+ }
else if (!DRW_state_draw_background()) {
background_type = BG_CHECKER;
}
diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.c b/source/blender/draw/engines/overlay/overlay_edit_uv.c
new file mode 100644
index 00000000000..109db6433e0
--- /dev/null
+++ b/source/blender/draw/engines/overlay/overlay_edit_uv.c
@@ -0,0 +1,394 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2019, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup draw_engine
+ */
+#include "DRW_render.h"
+
+#include "draw_cache_impl.h"
+#include "draw_manager_text.h"
+
+#include "BKE_image.h"
+
+#include "DNA_mesh_types.h"
+
+#include "ED_image.h"
+
+#include "GPU_batch.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "overlay_private.h"
+
+typedef struct OVERLAY_StretchingAreaTotals {
+ void *next, *prev;
+ float *total_area;
+ float *total_area_uv;
+} OVERLAY_StretchingAreaTotals;
+
+static OVERLAY_UVLineStyle edit_uv_line_style_from_space_image(const SpaceImage *sima)
+{
+ const bool is_uv_editor = sima->mode == SI_MODE_UV;
+ if (is_uv_editor) {
+ switch (sima->dt_uv) {
+ case SI_UVDT_OUTLINE:
+ return OVERLAY_UV_LINE_STYLE_OUTLINE;
+ case SI_UVDT_BLACK:
+ return OVERLAY_UV_LINE_STYLE_BLACK;
+ case SI_UVDT_WHITE:
+ return OVERLAY_UV_LINE_STYLE_WHITE;
+ case SI_UVDT_DASH:
+ return OVERLAY_UV_LINE_STYLE_DASH;
+ default:
+ return OVERLAY_UV_LINE_STYLE_BLACK;
+ }
+ }
+ else {
+ return OVERLAY_UV_LINE_STYLE_SHADOW;
+ }
+}
+
+/* -------------------------------------------------------------------- */
+/** \name Internal API
+ * \{ */
+
+void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
+{
+ OVERLAY_StorageList *stl = vedata->stl;
+ OVERLAY_PrivateData *pd = stl->pd;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
+ const Scene *scene = draw_ctx->scene;
+ const ToolSettings *ts = scene->toolsettings;
+
+ Image *image = sima->image;
+ /* By design no image is an image type. This so editor shows UV's by default. */
+ const bool is_image_type =
+ (image == NULL) || ELEM(image->type, IMA_TYPE_IMAGE, IMA_TYPE_MULTILAYER, IMA_TYPE_UV_TEST);
+ const bool is_uv_editor = sima->mode == SI_MODE_UV;
+ const bool has_edit_object = (draw_ctx->object_edit) != NULL;
+ const bool is_paint_mode = sima->mode == SI_MODE_PAINT;
+ const bool is_view_mode = sima->mode == SI_MODE_VIEW;
+ const bool is_edit_mode = draw_ctx->object_mode == OB_MODE_EDIT;
+ const bool do_uv_overlay = is_image_type && is_uv_editor && has_edit_object;
+ const bool show_modified_uvs = sima->flag & SI_DRAWSHADOW;
+ const bool is_tiled_image = image && (image->source == IMA_SRC_TILED);
+ const bool do_faces = ((sima->flag & SI_NO_DRAWFACES) == 0);
+ const bool do_face_dots = (ts->uv_flag & UV_SYNC_SELECTION) ?
+ (ts->selectmode & SCE_SELECT_FACE) != 0 :
+ (ts->uv_selectmode == UV_SELECT_FACE);
+ const bool do_uvstretching_overlay = is_image_type && is_uv_editor && is_edit_mode &&
+ ((sima->flag & SI_DRAW_STRETCH) != 0);
+ pd->edit_uv.do_faces = do_faces && !do_uvstretching_overlay;
+ pd->edit_uv.do_face_dots = do_faces && do_face_dots;
+
+ pd->edit_uv.do_uv_overlay = do_uv_overlay;
+ pd->edit_uv.do_uv_shadow_overlay =
+ is_image_type &&
+ ((is_paint_mode &&
+ ((draw_ctx->object_mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_EDIT)) != 0)) ||
+ (is_view_mode && ((draw_ctx->object_mode & (OB_MODE_TEXTURE_PAINT)) != 0)) ||
+ (do_uv_overlay && (show_modified_uvs)));
+ pd->edit_uv.do_uv_stretching_overlay = do_uvstretching_overlay;
+ pd->edit_uv.uv_opacity = sima->uv_opacity;
+ pd->edit_uv.do_tiled_image_overlay = is_image_type && is_tiled_image;
+
+ pd->edit_uv.dash_length = 4.0f * UI_DPI_FAC;
+ pd->edit_uv.line_style = edit_uv_line_style_from_space_image(sima);
+ pd->edit_uv.do_smooth_wire = ((U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) > 0);
+
+ pd->edit_uv.draw_type = sima->dt_uvstretch;
+ BLI_listbase_clear(&pd->edit_uv.totals);
+ pd->edit_uv.total_area_ratio = 0.0f;
+ pd->edit_uv.total_area_ratio_inv = 0.0f;
+
+ ED_space_image_get_uv_aspect(sima, &pd->edit_uv.aspect[0], &pd->edit_uv.aspect[1]);
+}
+
+void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
+{
+ OVERLAY_StorageList *stl = vedata->stl;
+ OVERLAY_PassList *psl = vedata->psl;
+ OVERLAY_PrivateData *pd = stl->pd;
+
+ if (pd->edit_uv.do_uv_overlay || pd->edit_uv.do_uv_shadow_overlay) {
+ /* uv edges */
+ {
+ DRW_PASS_CREATE(psl->edit_uv_edges_ps,
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
+ DRW_STATE_BLEND_ALPHA);
+ GPUShader *sh = OVERLAY_shader_edit_uv_edges_get();
+ if (pd->edit_uv.do_uv_shadow_overlay) {
+ pd->edit_uv_shadow_edges_grp = DRW_shgroup_create(sh, psl->edit_uv_edges_ps);
+ DRW_shgroup_uniform_block(pd->edit_uv_shadow_edges_grp, "globalsBlock", G_draw.block_ubo);
+ DRW_shgroup_uniform_int_copy(
+ pd->edit_uv_shadow_edges_grp, "lineStyle", OVERLAY_UV_LINE_STYLE_SHADOW);
+ DRW_shgroup_uniform_float_copy(
+ pd->edit_uv_shadow_edges_grp, "alpha", pd->edit_uv.uv_opacity);
+ DRW_shgroup_uniform_float(
+ pd->edit_uv_shadow_edges_grp, "dashLength", &pd->edit_uv.dash_length, 1);
+ DRW_shgroup_uniform_bool(
+ pd->edit_uv_shadow_edges_grp, "doSmoothWire", &pd->edit_uv.do_smooth_wire, 1);
+ }
+
+ if (pd->edit_uv.do_uv_overlay) {
+ pd->edit_uv_edges_grp = DRW_shgroup_create(sh, psl->edit_uv_edges_ps);
+ DRW_shgroup_uniform_block(pd->edit_uv_edges_grp, "globalsBlock", G_draw.block_ubo);
+ DRW_shgroup_uniform_int_copy(pd->edit_uv_edges_grp, "lineStyle", pd->edit_uv.line_style);
+ DRW_shgroup_uniform_float_copy(pd->edit_uv_edges_grp, "alpha", pd->edit_uv.uv_opacity);
+ DRW_shgroup_uniform_float(
+ pd->edit_uv_edges_grp, "dashLength", &pd->edit_uv.dash_length, 1);
+ DRW_shgroup_uniform_bool(
+ pd->edit_uv_edges_grp, "doSmoothWire", &pd->edit_uv.do_smooth_wire, 1);
+ }
+ }
+ }
+
+ if (pd->edit_uv.do_uv_overlay) {
+ /* uv verts */
+ {
+ DRW_PASS_CREATE(psl->edit_uv_verts_ps,
+ DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
+ DRW_STATE_BLEND_ALPHA);
+ GPUShader *sh = OVERLAY_shader_edit_uv_verts_get();
+ pd->edit_uv_verts_grp = DRW_shgroup_create(sh, psl->edit_uv_verts_ps);
+
+ const float point_size = UI_GetThemeValuef(TH_FACEDOT_SIZE);
+
+ DRW_shgroup_uniform_block(pd->edit_uv_verts_grp, "globalsBlock", G_draw.block_ubo);
+ DRW_shgroup_uniform_float_copy(
+ pd->edit_uv_verts_grp, "pointSize", (point_size + 1.5f) * M_SQRT2);
+ DRW_shgroup_uniform_float_copy(pd->edit_uv_verts_grp, "outlineWidth", 0.75f);
+ }
+
+ /* uv faces */
+ if (pd->edit_uv.do_faces) {
+ DRW_PASS_CREATE(psl->edit_uv_faces_ps,
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA);
+ GPUShader *sh = OVERLAY_shader_edit_uv_face_get();
+ pd->edit_uv_faces_grp = DRW_shgroup_create(sh, psl->edit_uv_faces_ps);
+ DRW_shgroup_uniform_block(pd->edit_uv_faces_grp, "globalsBlock", G_draw.block_ubo);
+ DRW_shgroup_uniform_float(pd->edit_uv_faces_grp, "uvOpacity", &pd->edit_uv.uv_opacity, 1);
+ }
+
+ /* uv face dots */
+ if (pd->edit_uv.do_face_dots) {
+ const float point_size = UI_GetThemeValuef(TH_FACEDOT_SIZE);
+ GPUShader *sh = OVERLAY_shader_edit_uv_face_dots_get();
+ pd->edit_uv_face_dots_grp = DRW_shgroup_create(sh, psl->edit_uv_verts_ps);
+ DRW_shgroup_uniform_block(pd->edit_uv_face_dots_grp, "globalsBlock", G_draw.block_ubo);
+ DRW_shgroup_uniform_float_copy(pd->edit_uv_face_dots_grp, "pointSize", point_size);
+ }
+ }
+
+ /* uv stretching */
+ if (pd->edit_uv.do_uv_stretching_overlay) {
+ DRW_PASS_CREATE(psl->edit_uv_stretching_ps,
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA);
+ if (pd->edit_uv.draw_type == SI_UVDT_STRETCH_ANGLE) {
+ GPUShader *sh = OVERLAY_shader_edit_uv_stretching_angle_get();
+ pd->edit_uv_stretching_grp = DRW_shgroup_create(sh, psl->edit_uv_stretching_ps);
+ DRW_shgroup_uniform_block(pd->edit_uv_stretching_grp, "globalsBlock", G_draw.block_ubo);
+ DRW_shgroup_uniform_vec2_copy(pd->edit_uv_stretching_grp, "aspect", pd->edit_uv.aspect);
+ }
+ else /* SI_UVDT_STRETCH_AREA */ {
+ GPUShader *sh = OVERLAY_shader_edit_uv_stretching_area_get();
+ pd->edit_uv_stretching_grp = DRW_shgroup_create(sh, psl->edit_uv_stretching_ps);
+ DRW_shgroup_uniform_block(pd->edit_uv_stretching_grp, "globalsBlock", G_draw.block_ubo);
+ DRW_shgroup_uniform_float(
+ pd->edit_uv_stretching_grp, "totalAreaRatio", &pd->edit_uv.total_area_ratio, 1);
+ DRW_shgroup_uniform_float(
+ pd->edit_uv_stretching_grp, "totalAreaRatioInv", &pd->edit_uv.total_area_ratio_inv, 1);
+ }
+ }
+
+ if (pd->edit_uv.do_tiled_image_overlay) {
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
+ Image *image = sima->image;
+ GPUBatch *geom = DRW_cache_quad_wires_get();
+ float obmat[4][4];
+ unit_m4(obmat);
+
+ DRW_PASS_CREATE(psl->edit_uv_tiled_image_borders_ps,
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS);
+ GPUShader *sh = OVERLAY_shader_edit_uv_tiled_image_borders_get();
+
+ float theme_color[4], selected_color[4];
+ UI_GetThemeColorShade4fv(TH_BACK, 60, theme_color);
+ UI_GetThemeColor4fv(TH_FACE_SELECT, selected_color);
+ srgb_to_linearrgb_v4(theme_color, theme_color);
+ srgb_to_linearrgb_v4(selected_color, selected_color);
+
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->edit_uv_tiled_image_borders_ps);
+ DRW_shgroup_uniform_vec4_copy(grp, "color", theme_color);
+ DRW_shgroup_uniform_vec3_copy(grp, "offset", (float[3]){0.0f, 0.0f, 0.0f});
+
+ LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
+ const int tile_x = ((tile->tile_number - 1001) % 10);
+ const int tile_y = ((tile->tile_number - 1001) / 10);
+ obmat[3][1] = (float)tile_y;
+ obmat[3][0] = (float)tile_x;
+ DRW_shgroup_call_obmat(grp, geom, obmat);
+ }
+
+ /* Active tile border */
+ ImageTile *active_tile = BLI_findlink(&image->tiles, image->active_tile_index);
+ obmat[3][0] = (float)((active_tile->tile_number - 1001) % 10);
+ obmat[3][1] = (float)((active_tile->tile_number - 1001) / 10);
+ grp = DRW_shgroup_create(sh, psl->edit_uv_tiled_image_borders_ps);
+ DRW_shgroup_uniform_vec4_copy(grp, "color", selected_color);
+ DRW_shgroup_call_obmat(grp, geom, obmat);
+
+ struct DRWTextStore *dt = DRW_text_cache_ensure();
+ uchar color[4];
+ /* Color Management: Exception here as texts are drawn in sRGB space directly. */
+ UI_GetThemeColorShade4ubv(TH_BACK, 60, color);
+ char text[16];
+ LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
+ BLI_snprintf(text, 5, "%d", tile->tile_number);
+ float tile_location[3] = {
+ ((tile->tile_number - 1001) % 10), ((tile->tile_number - 1001) / 10), 0.0f};
+ DRW_text_cache_add(dt,
+ tile_location,
+ text,
+ strlen(text),
+ 10,
+ 10,
+ DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_ASCII,
+ color);
+ }
+ }
+}
+
+void OVERLAY_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob)
+{
+ OVERLAY_StorageList *stl = vedata->stl;
+ OVERLAY_PrivateData *pd = stl->pd;
+ GPUBatch *geom;
+ const bool is_edit_object = DRW_object_is_in_edit_mode(ob);
+
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const bool draw_shadows = (draw_ctx->object_mode != OB_MODE_OBJECT) &&
+ (ob->mode == draw_ctx->object_mode);
+ if (is_edit_object) {
+ if (pd->edit_uv.do_uv_overlay) {
+ geom = DRW_mesh_batch_cache_get_edituv_edges(ob->data);
+ if (geom) {
+ DRW_shgroup_call_obmat(pd->edit_uv_edges_grp, geom, NULL);
+ }
+ geom = DRW_mesh_batch_cache_get_edituv_verts(ob->data);
+ if (geom) {
+ DRW_shgroup_call_obmat(pd->edit_uv_verts_grp, geom, NULL);
+ }
+ if (pd->edit_uv.do_faces) {
+ geom = DRW_mesh_batch_cache_get_edituv_faces(ob->data);
+ if (geom) {
+ DRW_shgroup_call_obmat(pd->edit_uv_faces_grp, geom, NULL);
+ }
+ }
+ if (pd->edit_uv.do_face_dots) {
+ geom = DRW_mesh_batch_cache_get_edituv_facedots(ob->data);
+ if (geom) {
+ DRW_shgroup_call_obmat(pd->edit_uv_face_dots_grp, geom, NULL);
+ }
+ }
+ }
+
+ if (pd->edit_uv.do_uv_stretching_overlay) {
+ Mesh *me = ob->data;
+
+ if (pd->edit_uv.draw_type == SI_UVDT_STRETCH_ANGLE) {
+ geom = DRW_mesh_batch_cache_get_edituv_faces_stretch_angle(me);
+ }
+ else /* SI_UVDT_STRETCH_AREA */ {
+ OVERLAY_StretchingAreaTotals *totals = MEM_mallocN(sizeof(OVERLAY_StretchingAreaTotals),
+ __func__);
+ BLI_addtail(&pd->edit_uv.totals, totals);
+ geom = DRW_mesh_batch_cache_get_edituv_faces_stretch_area(
+ me, &totals->total_area, &totals->total_area_uv);
+ }
+
+ if (geom) {
+ DRW_shgroup_call_obmat(pd->edit_uv_stretching_grp, geom, NULL);
+ }
+ }
+ }
+
+ if (draw_shadows) {
+ if (pd->edit_uv.do_uv_shadow_overlay) {
+ geom = DRW_mesh_batch_cache_get_uv_edges(ob->data);
+ if (geom) {
+ DRW_shgroup_call_obmat(pd->edit_uv_shadow_edges_grp, geom, NULL);
+ }
+ }
+ }
+}
+
+static void edit_uv_stretching_update_ratios(OVERLAY_Data *vedata)
+{
+ OVERLAY_StorageList *stl = vedata->stl;
+ OVERLAY_PrivateData *pd = stl->pd;
+
+ if (pd->edit_uv.draw_type == SI_UVDT_STRETCH_AREA) {
+ float total_area = 0.0f;
+ float total_area_uv = 0.0f;
+
+ LISTBASE_FOREACH (OVERLAY_StretchingAreaTotals *, totals, &pd->edit_uv.totals) {
+ total_area += *totals->total_area;
+ total_area_uv += *totals->total_area_uv;
+ }
+
+ if (total_area > FLT_EPSILON && total_area_uv > FLT_EPSILON) {
+ pd->edit_uv.total_area_ratio = total_area / total_area_uv;
+ pd->edit_uv.total_area_ratio_inv = total_area_uv / total_area;
+ }
+ }
+ BLI_freelistN(&pd->edit_uv.totals);
+}
+
+void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata)
+{
+ OVERLAY_PassList *psl = vedata->psl;
+ OVERLAY_StorageList *stl = vedata->stl;
+ OVERLAY_PrivateData *pd = stl->pd;
+
+ if (pd->edit_uv.do_tiled_image_overlay) {
+ DRW_draw_pass(psl->edit_uv_tiled_image_borders_ps);
+ }
+
+ if (pd->edit_uv.do_uv_stretching_overlay) {
+ edit_uv_stretching_update_ratios(vedata);
+ DRW_draw_pass(psl->edit_uv_stretching_ps);
+ }
+ if (pd->edit_uv.do_uv_overlay) {
+ if (pd->edit_uv.do_faces) {
+ DRW_draw_pass(psl->edit_uv_faces_ps);
+ }
+ DRW_draw_pass(psl->edit_uv_edges_ps);
+
+ DRW_draw_pass(psl->edit_uv_verts_ps);
+ }
+ else if (pd->edit_uv.do_uv_shadow_overlay) {
+ DRW_draw_pass(psl->edit_uv_edges_ps);
+ }
+}
+
+/* \{ */
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index 1312408498a..9cdd371ec4e 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -29,9 +29,13 @@
#include "ED_view3d.h"
+#include "UI_interface.h"
+
#include "BKE_object.h"
#include "BKE_paint.h"
+#include "DNA_space_types.h"
+
#include "overlay_engine.h"
#include "overlay_private.h"
@@ -48,6 +52,10 @@ static void OVERLAY_engine_init(void *vedata)
const View3D *v3d = draw_ctx->v3d;
const Scene *scene = draw_ctx->scene;
const ToolSettings *ts = scene->toolsettings;
+ const SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
+ BLI_assert(v3d || sima);
+
+ OVERLAY_shader_library_ensure();
if (!stl->pd) {
/* Alloc transient pointers */
@@ -55,6 +63,14 @@ static void OVERLAY_engine_init(void *vedata)
}
OVERLAY_PrivateData *pd = stl->pd;
+ pd->is_image_editor = sima != NULL;
+
+ if (pd->is_image_editor) {
+ pd->clipping_state = 0;
+ OVERLAY_grid_init(data);
+ OVERLAY_edit_uv_init(data);
+ return;
+ }
pd->hide_overlays = (v3d->flag2 & V3D_HIDE_OVERLAYS) != 0;
pd->ctx_mode = CTX_data_mode_enum_ex(
@@ -122,6 +138,13 @@ static void OVERLAY_cache_init(void *vedata)
OVERLAY_StorageList *stl = data->stl;
OVERLAY_PrivateData *pd = stl->pd;
+ if (pd->is_image_editor) {
+ OVERLAY_background_cache_init(vedata);
+ OVERLAY_grid_cache_init(vedata);
+ OVERLAY_edit_uv_cache_init(vedata);
+ return;
+ }
+
switch (pd->ctx_mode) {
case CTX_MODE_EDIT_MESH:
OVERLAY_edit_mesh_cache_init(vedata);
@@ -240,6 +263,14 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
{
OVERLAY_Data *data = vedata;
OVERLAY_PrivateData *pd = data->stl->pd;
+
+ if (pd->is_image_editor) {
+ if (ob->type == OB_MESH) {
+ OVERLAY_edit_uv_cache_populate(vedata, ob);
+ }
+ return;
+ }
+
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool is_select = DRW_state_is_select();
const bool renderable = DRW_object_is_renderable(ob);
@@ -414,6 +445,12 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob)
static void OVERLAY_cache_finish(void *vedata)
{
+ OVERLAY_Data *data = vedata;
+ OVERLAY_PrivateData *pd = data->stl->pd;
+ if (pd->is_image_editor) {
+ return;
+ }
+
/* TODO(fclem) Only do this when really needed. */
{
/* HACK we allocate the in front depth here to avoid the overhead when if is not needed. */
@@ -445,6 +482,16 @@ static void OVERLAY_draw_scene(void *vedata)
GPU_framebuffer_clear_color(dfbl->overlay_only_fb, clear_col);
}
+ if (pd->is_image_editor) {
+ OVERLAY_background_draw(data);
+ OVERLAY_grid_draw(data);
+ if (DRW_state_is_fbo()) {
+ GPU_framebuffer_bind(dfbl->overlay_fb);
+ }
+ OVERLAY_edit_uv_draw(data);
+ return;
+ }
+
OVERLAY_image_background_draw(vedata);
OVERLAY_background_draw(vedata);
diff --git a/source/blender/draw/engines/overlay/overlay_grid.c b/source/blender/draw/engines/overlay/overlay_grid.c
index e3079870d8f..7445dfc2e3d 100644
--- a/source/blender/draw/engines/overlay/overlay_grid.c
+++ b/source/blender/draw/engines/overlay/overlay_grid.c
@@ -26,6 +26,7 @@
#include "DEG_depsgraph_query.h"
+#include "ED_image.h"
#include "ED_view3d.h"
#include "overlay_private.h"
@@ -42,14 +43,31 @@ enum {
CLIP_ZNEG = (1 << 8),
GRID_BACK = (1 << 9),
GRID_CAMERA = (1 << 10),
+ PLANE_IMAGE = (1 << 11),
};
void OVERLAY_grid_init(OVERLAY_Data *vedata)
{
OVERLAY_PrivateData *pd = vedata->stl->pd;
OVERLAY_ShadingData *shd = &pd->shdata;
-
const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ shd->grid_flag = 0;
+ shd->zneg_flag = 0;
+ shd->zpos_flag = 0;
+ shd->grid_line_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
+
+ if (pd->is_image_editor) {
+ SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
+ shd->grid_flag = ED_space_image_has_buffer(sima) ? 0 : PLANE_IMAGE | SHOW_GRID;
+ shd->grid_distance = 1.0f;
+ shd->grid_mesh_size = 1.0f;
+ for (int step = 0; step < 8; step++) {
+ shd->grid_steps[step] = powf(4, step) * (1.0f / 16.0f);
+ }
+ return;
+ }
+
View3D *v3d = draw_ctx->v3d;
Scene *scene = draw_ctx->scene;
RegionView3D *rv3d = draw_ctx->rv3d;
@@ -60,10 +78,6 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
const bool show_floor = (pd->v3d_gridflag & V3D_SHOW_FLOOR) != 0;
const bool show_ortho_grid = (pd->v3d_gridflag & V3D_SHOW_ORTHO_GRID) != 0;
- shd->grid_flag = 0;
- shd->zneg_flag = 0;
- shd->zpos_flag = 0;
-
if (pd->hide_overlays || !(pd->v3d_gridflag & (V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z |
V3D_SHOW_FLOOR | V3D_SHOW_ORTHO_GRID))) {
return;
@@ -163,14 +177,16 @@ void OVERLAY_grid_init(OVERLAY_Data *vedata)
}
shd->grid_distance = dist / 2.0f;
- shd->grid_line_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
ED_view3d_grid_steps(scene, v3d, rv3d, shd->grid_steps);
}
void OVERLAY_grid_cache_init(OVERLAY_Data *vedata)
{
- OVERLAY_ShadingData *shd = &vedata->stl->pd->shdata;
+ OVERLAY_StorageList *stl = vedata->stl;
+ OVERLAY_PrivateData *pd = stl->pd;
+ OVERLAY_ShadingData *shd = &pd->shdata;
+
OVERLAY_PassList *psl = vedata->psl;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -182,12 +198,29 @@ void OVERLAY_grid_cache_init(OVERLAY_Data *vedata)
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->grid_ps, state);
-
- GPUShader *sh = OVERLAY_shader_grid();
+ DRWShadingGroup *grp;
+ GPUShader *sh;
struct GPUBatch *geom = DRW_cache_grid_get();
+ if (pd->is_image_editor) {
+ /* add quad background */
+ sh = OVERLAY_shader_grid_image();
+ grp = DRW_shgroup_create(sh, psl->grid_ps);
+ DRW_shgroup_call(grp, DRW_cache_quad_get(), NULL);
+ float color_back[4];
+ interp_v4_v4v4(color_back, G_draw.block.colorBackground, G_draw.block.colorGrid, 0.5);
+ DRW_shgroup_uniform_vec4_copy(grp, "color", color_back);
+
+ /* add wire border */
+ grp = DRW_shgroup_create(sh, psl->grid_ps);
+ DRW_shgroup_call(grp, DRW_cache_quad_wires_get(), NULL);
+ DRW_shgroup_uniform_vec4_copy(grp, "color", G_draw.block.colorGrid);
+ }
+
+ sh = OVERLAY_shader_grid();
+
/* Create 3 quads to render ordered transparency Z axis */
- DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->grid_ps);
+ grp = DRW_shgroup_create(sh, psl->grid_ps);
DRW_shgroup_uniform_int(grp, "gridFlag", &shd->zneg_flag, 1);
DRW_shgroup_uniform_vec3(grp, "planeAxes", shd->zplane_axes, 1);
DRW_shgroup_uniform_float(grp, "gridDistance", &shd->grid_distance, 1);
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index c9d29af91e6..c8b29c6bbbb 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -34,6 +34,9 @@ extern "C" {
# define USE_GEOM_SHADER_WORKAROUND 0
#endif
+/* Needed for eSpaceImage_UVDT_Stretch */
+#include "DNA_space_types.h"
+
typedef struct OVERLAY_FramebufferList {
struct GPUFrameBuffer *overlay_default_fb;
struct GPUFrameBuffer *overlay_line_fb;
@@ -55,6 +58,14 @@ typedef struct OVERLAY_TextureList {
#define NOT_IN_FRONT 0
#define IN_FRONT 1
+typedef enum OVERLAY_UVLineStyle {
+ OVERLAY_UV_LINE_STYLE_OUTLINE = 0,
+ OVERLAY_UV_LINE_STYLE_DASH = 1,
+ OVERLAY_UV_LINE_STYLE_BLACK = 2,
+ OVERLAY_UV_LINE_STYLE_WHITE = 3,
+ OVERLAY_UV_LINE_STYLE_SHADOW = 4,
+} OVERLAY_UVLineStyle;
+
typedef struct OVERLAY_PassList {
DRWPass *antialiasing_ps;
DRWPass *armature_ps[2];
@@ -78,6 +89,11 @@ typedef struct OVERLAY_PassList {
DRWPass *edit_text_overlay_ps;
DRWPass *edit_text_darken_ps;
DRWPass *edit_text_wire_ps[2];
+ DRWPass *edit_uv_edges_ps;
+ DRWPass *edit_uv_verts_ps;
+ DRWPass *edit_uv_faces_ps;
+ DRWPass *edit_uv_stretching_ps;
+ DRWPass *edit_uv_tiled_image_borders_ps;
DRWPass *extra_ps[2];
DRWPass *extra_blend_ps;
DRWPass *extra_centers_ps;
@@ -244,6 +260,12 @@ typedef struct OVERLAY_PrivateData {
DRWShadingGroup *edit_particle_point_grp;
DRWShadingGroup *edit_text_overlay_grp;
DRWShadingGroup *edit_text_wire_grp[2];
+ DRWShadingGroup *edit_uv_verts_grp;
+ DRWShadingGroup *edit_uv_edges_grp;
+ DRWShadingGroup *edit_uv_shadow_edges_grp;
+ DRWShadingGroup *edit_uv_faces_grp;
+ DRWShadingGroup *edit_uv_face_dots_grp;
+ DRWShadingGroup *edit_uv_stretching_grp;
DRWShadingGroup *extra_grid_grp;
DRWShadingGroup *facing_grp[2];
DRWShadingGroup *motion_path_lines_grp;
@@ -286,6 +308,7 @@ typedef struct OVERLAY_PrivateData {
View3DOverlay overlay;
enum eContextObjectMode ctx_mode;
+ bool is_image_editor;
bool clear_in_front;
bool use_in_front;
bool wireframe_mode;
@@ -325,6 +348,29 @@ typedef struct OVERLAY_PrivateData {
int select_mode;
} edit_particle;
struct {
+ bool do_uv_overlay;
+ bool do_uv_shadow_overlay;
+ bool do_uv_stretching_overlay;
+ bool do_tiled_image_overlay;
+
+ bool do_faces;
+ bool do_face_dots;
+
+ float uv_opacity;
+ /* edge drawing */
+ OVERLAY_UVLineStyle line_style;
+ float dash_length;
+ int do_smooth_wire;
+
+ /* stretching overlay */
+ float aspect[2];
+ eSpaceImage_UVDT_Stretch draw_type;
+ ListBase totals;
+ float total_area_ratio;
+ float total_area_ratio_inv;
+
+ } edit_uv;
+ struct {
bool transparent;
bool show_relations;
bool do_pose_xray;
@@ -472,6 +518,11 @@ void OVERLAY_edit_particle_cache_init(OVERLAY_Data *vedata);
void OVERLAY_edit_particle_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_edit_particle_draw(OVERLAY_Data *vedata);
+void OVERLAY_edit_uv_init(OVERLAY_Data *vedata);
+void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata);
+void OVERLAY_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob);
+void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata);
+
void OVERLAY_extra_cache_init(OVERLAY_Data *vedata);
void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob);
void OVERLAY_extra_blend_draw(OVERLAY_Data *vedata);
@@ -570,6 +621,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
void OVERLAY_wireframe_draw(OVERLAY_Data *vedata);
void OVERLAY_wireframe_in_front_draw(OVERLAY_Data *vedata);
+void OVERLAY_shader_library_ensure(void);
GPUShader *OVERLAY_shader_antialiasing(void);
GPUShader *OVERLAY_shader_armature_degrees_of_freedom_wire(void);
GPUShader *OVERLAY_shader_armature_degrees_of_freedom_solid(void);
@@ -599,6 +651,13 @@ GPUShader *OVERLAY_shader_edit_mesh_skin_root(void);
GPUShader *OVERLAY_shader_edit_mesh_vert(void);
GPUShader *OVERLAY_shader_edit_particle_strand(void);
GPUShader *OVERLAY_shader_edit_particle_point(void);
+GPUShader *OVERLAY_shader_edit_uv_edges_get(void);
+GPUShader *OVERLAY_shader_edit_uv_face_get(void);
+GPUShader *OVERLAY_shader_edit_uv_face_dots_get(void);
+GPUShader *OVERLAY_shader_edit_uv_verts_get(void);
+GPUShader *OVERLAY_shader_edit_uv_stretching_area_get(void);
+GPUShader *OVERLAY_shader_edit_uv_stretching_angle_get(void);
+GPUShader *OVERLAY_shader_edit_uv_tiled_image_borders_get(void);
GPUShader *OVERLAY_shader_extra(bool is_select);
GPUShader *OVERLAY_shader_extra_groundline(void);
GPUShader *OVERLAY_shader_extra_wire(bool use_object, bool is_select);
@@ -607,6 +666,7 @@ GPUShader *OVERLAY_shader_extra_point(void);
GPUShader *OVERLAY_shader_facing(void);
GPUShader *OVERLAY_shader_gpencil_canvas(void);
GPUShader *OVERLAY_shader_grid(void);
+GPUShader *OVERLAY_shader_grid_image(void);
GPUShader *OVERLAY_shader_image(void);
GPUShader *OVERLAY_shader_motion_path_line(void);
GPUShader *OVERLAY_shader_motion_path_vert(void);
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c
index e3cb052890b..4530d6e8adf 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.c
@@ -70,6 +70,15 @@ extern char datatoc_edit_mesh_analysis_vert_glsl[];
extern char datatoc_edit_mesh_analysis_frag_glsl[];
extern char datatoc_edit_particle_strand_vert_glsl[];
extern char datatoc_edit_particle_point_vert_glsl[];
+extern char datatoc_edit_uv_verts_vert_glsl[];
+extern char datatoc_edit_uv_verts_frag_glsl[];
+extern char datatoc_edit_uv_edges_vert_glsl[];
+extern char datatoc_edit_uv_edges_geom_glsl[];
+extern char datatoc_edit_uv_edges_frag_glsl[];
+extern char datatoc_edit_uv_faces_vert_glsl[];
+extern char datatoc_edit_uv_face_dots_vert_glsl[];
+extern char datatoc_edit_uv_stretching_vert_glsl[];
+extern char datatoc_edit_uv_tiled_image_borders_vert_glsl[];
extern char datatoc_extra_frag_glsl[];
extern char datatoc_extra_vert_glsl[];
extern char datatoc_extra_groundline_vert_glsl[];
@@ -113,6 +122,7 @@ extern char datatoc_xray_fade_frag_glsl[];
extern char datatoc_gpu_shader_depth_only_frag_glsl[];
extern char datatoc_gpu_shader_point_varying_color_frag_glsl[];
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
+extern char datatoc_gpu_shader_2D_smooth_color_frag_glsl[];
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
extern char datatoc_gpu_shader_flat_color_frag_glsl[];
extern char datatoc_gpu_shader_point_varying_color_varying_outline_aa_frag_glsl[];
@@ -120,6 +130,7 @@ extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
extern char datatoc_gpencil_common_lib_glsl[];
+extern char datatoc_common_overlay_lib_glsl[];
extern char datatoc_common_colormanagement_lib_glsl[];
extern char datatoc_common_fullscreen_vert_glsl[];
extern char datatoc_common_fxaa_lib_glsl[];
@@ -164,6 +175,13 @@ typedef struct OVERLAY_Shaders {
GPUShader *edit_mesh_analysis;
GPUShader *edit_particle_strand;
GPUShader *edit_particle_point;
+ GPUShader *edit_uv_verts;
+ GPUShader *edit_uv_faces;
+ GPUShader *edit_uv_edges;
+ GPUShader *edit_uv_face_dots;
+ GPUShader *edit_uv_stretching_angle;
+ GPUShader *edit_uv_stretching_area;
+ GPUShader *edit_uv_tiled_image_borders;
GPUShader *extra;
GPUShader *extra_select;
GPUShader *extra_groundline;
@@ -175,6 +193,7 @@ typedef struct OVERLAY_Shaders {
GPUShader *facing;
GPUShader *gpencil_canvas;
GPUShader *grid;
+ GPUShader *grid_image;
GPUShader *image;
GPUShader *motion_path_line;
GPUShader *motion_path_vert;
@@ -203,8 +222,20 @@ typedef struct OVERLAY_Shaders {
static struct {
OVERLAY_Shaders sh_data[GPU_SHADER_CFG_LEN];
+ DRWShaderLibrary *lib;
} e_data = {{{NULL}}};
+void OVERLAY_shader_library_ensure(void)
+{
+ if (e_data.lib == NULL) {
+ e_data.lib = DRW_shader_library_create();
+ /* NOTE: Theses needs to be ordered by dependencies. */
+ DRW_SHADER_LIB_ADD(e_data.lib, common_globals_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_overlay_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
+ }
+}
+
GPUShader *OVERLAY_shader_antialiasing(void)
{
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
@@ -1012,6 +1043,20 @@ GPUShader *OVERLAY_shader_grid(void)
return sh_data->grid;
}
+GPUShader *OVERLAY_shader_grid_image(void)
+{
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
+ if (!sh_data->grid_image) {
+ sh_data->grid_image = DRW_shader_create_with_shaderlib(
+ datatoc_edit_uv_tiled_image_borders_vert_glsl,
+ NULL,
+ datatoc_gpu_shader_uniform_color_frag_glsl,
+ e_data.lib,
+ "#define blender_srgb_to_framebuffer_space(a) a\n");
+ }
+ return sh_data->grid_image;
+}
+
GPUShader *OVERLAY_shader_image(void)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -1449,6 +1494,108 @@ GPUShader *OVERLAY_shader_xray_fade(void)
return sh_data->xray_fade;
}
+/* -------------------------------------------------------------------- */
+/** \name Edit UV shaders
+ * \{ */
+
+GPUShader *OVERLAY_shader_edit_uv_edges_get(void)
+{
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
+ if (!sh_data->edit_uv_edges) {
+ sh_data->edit_uv_edges = DRW_shader_create_with_shaderlib(datatoc_edit_uv_edges_vert_glsl,
+ datatoc_edit_uv_edges_geom_glsl,
+ datatoc_edit_uv_edges_frag_glsl,
+ e_data.lib,
+ NULL);
+ }
+ return sh_data->edit_uv_edges;
+}
+
+GPUShader *OVERLAY_shader_edit_uv_face_get(void)
+{
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
+ if (!sh_data->edit_uv_faces) {
+ sh_data->edit_uv_faces = DRW_shader_create_with_shaderlib(
+ datatoc_edit_uv_faces_vert_glsl,
+ NULL,
+ datatoc_gpu_shader_flat_color_frag_glsl,
+ e_data.lib,
+ "#define blender_srgb_to_framebuffer_space(a) a\n");
+ }
+ return sh_data->edit_uv_faces;
+}
+
+GPUShader *OVERLAY_shader_edit_uv_face_dots_get(void)
+{
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
+ if (!sh_data->edit_uv_face_dots) {
+ sh_data->edit_uv_face_dots = DRW_shader_create_with_shaderlib(
+ datatoc_edit_uv_face_dots_vert_glsl,
+ NULL,
+ datatoc_gpu_shader_flat_color_frag_glsl,
+ e_data.lib,
+ "#define blender_srgb_to_framebuffer_space(a) a\n");
+ }
+ return sh_data->edit_uv_face_dots;
+}
+
+GPUShader *OVERLAY_shader_edit_uv_verts_get(void)
+{
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
+ if (!sh_data->edit_uv_verts) {
+ sh_data->edit_uv_verts = DRW_shader_create_with_shaderlib(
+ datatoc_edit_uv_verts_vert_glsl, NULL, datatoc_edit_uv_verts_frag_glsl, e_data.lib, NULL);
+ }
+
+ return sh_data->edit_uv_verts;
+}
+
+GPUShader *OVERLAY_shader_edit_uv_stretching_area_get(void)
+{
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
+ if (!sh_data->edit_uv_stretching_area) {
+ sh_data->edit_uv_stretching_area = DRW_shader_create_with_shaderlib(
+ datatoc_edit_uv_stretching_vert_glsl,
+ NULL,
+ datatoc_gpu_shader_2D_smooth_color_frag_glsl,
+ e_data.lib,
+ "#define blender_srgb_to_framebuffer_space(a) a\n");
+ }
+
+ return sh_data->edit_uv_stretching_area;
+}
+
+GPUShader *OVERLAY_shader_edit_uv_stretching_angle_get(void)
+{
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
+ if (!sh_data->edit_uv_stretching_angle) {
+ sh_data->edit_uv_stretching_angle = DRW_shader_create_with_shaderlib(
+ datatoc_edit_uv_stretching_vert_glsl,
+ NULL,
+ datatoc_gpu_shader_2D_smooth_color_frag_glsl,
+ e_data.lib,
+ "#define blender_srgb_to_framebuffer_space(a) a\n#define STRETCH_ANGLE\n");
+ }
+
+ return sh_data->edit_uv_stretching_angle;
+}
+
+GPUShader *OVERLAY_shader_edit_uv_tiled_image_borders_get(void)
+{
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
+ if (!sh_data->edit_uv_tiled_image_borders) {
+ sh_data->edit_uv_tiled_image_borders = DRW_shader_create_with_shaderlib(
+ datatoc_edit_uv_tiled_image_borders_vert_glsl,
+ NULL,
+ datatoc_gpu_shader_uniform_color_frag_glsl,
+ e_data.lib,
+ "#define blender_srgb_to_framebuffer_space(a) a\n");
+ }
+ return sh_data->edit_uv_tiled_image_borders;
+}
+
+/* \} */
+
static OVERLAY_InstanceFormats g_formats = {NULL};
OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void)
@@ -1521,6 +1668,8 @@ OVERLAY_InstanceFormats *OVERLAY_shader_instance_formats_get(void)
void OVERLAY_shader_free(void)
{
+ DRW_SHADER_LIB_FREE_SAFE(e_data.lib);
+
for (int sh_data_index = 0; sh_data_index < ARRAY_SIZE(e_data.sh_data); sh_data_index++) {
OVERLAY_Shaders *sh_data = &e_data.sh_data[sh_data_index];
GPUShader **sh_data_as_array = (GPUShader **)sh_data;
diff --git a/source/blender/draw/engines/overlay/shaders/background_frag.glsl b/source/blender/draw/engines/overlay/shaders/background_frag.glsl
index d5aaaf75b79..71bfd2f8e73 100644
--- a/source/blender/draw/engines/overlay/shaders/background_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/background_frag.glsl
@@ -13,6 +13,7 @@ out vec4 fragColor;
#define BG_GRADIENT 1
#define BG_CHECKER 2
#define BG_RADIAL 3
+#define BG_SOLID_CHECKER 4
#define SQRT2 1.4142135623730950488
/* 4x4 bayer matrix prepared for 8bit UNORM precision error. */
@@ -43,7 +44,11 @@ void main()
vec3 col_high;
vec3 col_low;
- switch (bgType) {
+ /* BG_SOLID_CHECKER selects BG_SOLID when no pixel has been drawn otherwise use the BG_CHERKER.
+ */
+ int bg_type = bgType == BG_SOLID_CHECKER ? (depth == 1.0 ? BG_SOLID : BG_CHECKER) : bgType;
+
+ switch (bg_type) {
case BG_SOLID:
bg_col = colorBackground.rgb;
break;
diff --git a/source/blender/draw/engines/overlay/shaders/common_overlay_lib.glsl b/source/blender/draw/engines/overlay/shaders/common_overlay_lib.glsl
new file mode 100644
index 00000000000..65aeb81a4ef
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/common_overlay_lib.glsl
@@ -0,0 +1,5 @@
+#define OVERLAY_UV_LINE_STYLE_OUTLINE 0
+#define OVERLAY_UV_LINE_STYLE_DASH 1
+#define OVERLAY_UV_LINE_STYLE_BLACK 2
+#define OVERLAY_UV_LINE_STYLE_WHITE 3
+#define OVERLAY_UV_LINE_STYLE_SHADOW 4
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_frag.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_edges_frag.glsl
new file mode 100644
index 00000000000..b81fdd2c712
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_edges_frag.glsl
@@ -0,0 +1,77 @@
+#pragma BLENDER_REQUIRE(common_globals_lib.glsl)
+#pragma BLENDER_REQUIRE(common_overlay_lib.glsl)
+
+uniform int lineStyle;
+uniform bool doSmoothWire;
+uniform float alpha;
+uniform float dashLength;
+
+in float selectionFac_f;
+noperspective in float edgeCoord_f;
+noperspective in vec2 stipplePos_f;
+flat in vec2 stippleStart_f;
+
+layout(location = 0) out vec4 fragColor;
+
+#define M_1_SQRTPI 0.5641895835477563 /* 1/sqrt(pi) */
+
+/**
+ * We want to know how much a pixel is covered by a line.
+ * We replace the square pixel with acircle of the same area and try to find the intersection area.
+ * The area we search is the circular segment. https://en.wikipedia.org/wiki/Circular_segment
+ * The formula for the area uses inverse trig function and is quite complexe. Instead,
+ * we approximate it by using the smoothstep function and a 1.05 factor to the disc radius.
+ */
+#define DISC_RADIUS (M_1_SQRTPI * 1.05)
+#define GRID_LINE_SMOOTH_START (0.5 - DISC_RADIUS)
+#define GRID_LINE_SMOOTH_END (0.5 + DISC_RADIUS)
+
+void main()
+{
+ vec4 inner_color = vec4(vec3(0.0), 1.0);
+ vec4 outer_color = vec4(0.0);
+
+ vec2 dd = fwidth(stipplePos_f);
+ float line_distance = distance(stipplePos_f, stippleStart_f) / max(dd.x, dd.y);
+
+ if (lineStyle == OVERLAY_UV_LINE_STYLE_OUTLINE) {
+ inner_color = mix(colorWireEdit, colorEdgeSelect, selectionFac_f);
+ outer_color = vec4(vec3(0.0), 1.0);
+ }
+ else if (lineStyle == OVERLAY_UV_LINE_STYLE_DASH) {
+ if (fract(line_distance / dashLength) < 0.5) {
+ inner_color = mix(vec4(1.0), colorEdgeSelect, selectionFac_f);
+ }
+ }
+ else if (lineStyle == OVERLAY_UV_LINE_STYLE_BLACK) {
+ vec4 base_color = vec4(vec3(0.0), 1.0);
+ inner_color = mix(base_color, colorEdgeSelect, selectionFac_f);
+ }
+ else if (lineStyle == OVERLAY_UV_LINE_STYLE_WHITE) {
+ vec4 base_color = vec4(1.0);
+ inner_color = mix(base_color, colorEdgeSelect, selectionFac_f);
+ }
+ else if (lineStyle == OVERLAY_UV_LINE_STYLE_SHADOW) {
+ inner_color = colorUVShadow;
+ }
+
+ float dist = abs(edgeCoord_f) - max(sizeEdge - 0.5, 0.0);
+ float dist_outer = dist - max(sizeEdge, 1.0);
+ float mix_w;
+ float mix_w_outer;
+
+ if (doSmoothWire) {
+ mix_w = smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, dist);
+ mix_w_outer = smoothstep(GRID_LINE_SMOOTH_START, GRID_LINE_SMOOTH_END, dist_outer);
+ }
+ else {
+ mix_w = step(0.5, dist);
+ mix_w_outer = step(0.5, dist_outer);
+ }
+
+ vec4 final_color = mix(outer_color, inner_color, 1.0 - mix_w * outer_color.a);
+ final_color.a *= 1.0 - (outer_color.a > 0.0 ? mix_w_outer : mix_w);
+ final_color.a *= alpha;
+
+ fragColor = final_color;
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_geom.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_edges_geom.glsl
new file mode 100644
index 00000000000..4f8d553a220
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_edges_geom.glsl
@@ -0,0 +1,63 @@
+#pragma BLENDER_REQUIRE(common_globals_lib.glsl)
+#pragma BLENDER_REQUIRE(common_overlay_lib.glsl)
+
+layout(lines) in;
+layout(triangle_strip, max_vertices = 4) out;
+
+in float selectionFac[2];
+flat in vec2 stippleStart[2];
+noperspective in vec2 stipplePos[2];
+
+uniform int lineStyle;
+uniform bool doSmoothWire;
+
+out float selectionFac_f;
+noperspective out float edgeCoord_f;
+noperspective out vec2 stipplePos_f;
+flat out vec2 stippleStart_f;
+
+void do_vertex(
+ vec4 pos, float selection_fac, vec2 stipple_start, vec2 stipple_pos, float coord, vec2 offset)
+{
+ selectionFac_f = selection_fac;
+ edgeCoord_f = coord;
+ stippleStart_f = stipple_start;
+ stipplePos_f = stipple_pos;
+
+ gl_Position = pos;
+ /* Multiply offset by 2 because gl_Position range is [-1..1]. */
+ gl_Position.xy += offset * 2.0;
+ EmitVertex();
+}
+
+void main()
+{
+ vec2 ss_pos[2];
+ vec4 pos0 = gl_in[0].gl_Position;
+ vec4 pos1 = gl_in[1].gl_Position;
+ ss_pos[0] = pos0.xy / pos0.w;
+ ss_pos[1] = pos1.xy / pos1.w;
+
+ float half_size = sizeEdge;
+ /* Enlarge edge for outline drawing. */
+ /* Factor of 3.0 out of nowhere! Seems to fix issues with float imprecision. */
+ half_size += (lineStyle == OVERLAY_UV_LINE_STYLE_OUTLINE) ?
+ max(sizeEdge * (doSmoothWire ? 1.0 : 3.0), 1.0) :
+ 0.0;
+ /* Add 1 px for AA */
+ if (doSmoothWire) {
+ half_size += 0.5;
+ }
+
+ vec2 line = ss_pos[0] - ss_pos[1];
+ vec2 line_dir = normalize(line);
+ vec2 line_perp = vec2(-line_dir.y, line_dir.x);
+ vec2 edge_ofs = line_perp * sizeViewportInv * ceil(half_size);
+
+ do_vertex(pos0, selectionFac[0], stippleStart[0], stipplePos[0], half_size, edge_ofs.xy);
+ do_vertex(pos0, selectionFac[0], stippleStart[0], stipplePos[0], -half_size, -edge_ofs.xy);
+ do_vertex(pos1, selectionFac[1], stippleStart[1], stipplePos[1], half_size, edge_ofs.xy);
+ do_vertex(pos1, selectionFac[1], stippleStart[1], stipplePos[1], -half_size, -edge_ofs.xy);
+
+ EndPrimitive();
+}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_edges_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_edges_vert.glsl
new file mode 100644
index 00000000000..4661cf248e6
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_edges_vert.glsl
@@ -0,0 +1,32 @@
+#pragma BLENDER_REQUIRE(common_globals_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+in vec3 pos;
+in vec2 u;
+in int flag;
+
+out float selectionFac;
+noperspective out vec2 stipplePos;
+flat out vec2 stippleStart;
+
+void main()
+{
+ vec3 world_pos = point_object_to_world(vec3(u, 0.0));
+ gl_Position = point_world_to_ndc(world_pos);
+ /* Snap vertices to the pixel grid to reduce artifacts. */
+ vec2 half_viewport_res = sizeViewport.xy * 0.5;
+ vec2 half_pixel_offset = sizeViewportInv * 0.5;
+ gl_Position.xy = floor(gl_Position.xy * half_viewport_res) / half_viewport_res +
+ half_pixel_offset;
+
+ bool is_select = (flag & VERT_UV_SELECT) != 0;
+ selectionFac = is_select ? 1.0 : 0.0;
+ /* Move selected edges to the top
+ * Vertices are between 0.0 and 0.2, Edges between 0.2 and 0.4
+ * actual pixels are at 0.75, 1.0 is used for the background. */
+ float depth = is_select ? 0.25 : 0.35;
+ gl_Position.z = depth;
+
+ /* Avoid precision loss. */
+ stippleStart = stipplePos = 500.0 + 500.0 * (gl_Position.xy / gl_Position.w);
+}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_face_dots_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_face_dots_vert.glsl
new file mode 100644
index 00000000000..61152c83a29
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_face_dots_vert.glsl
@@ -0,0 +1,18 @@
+#pragma BLENDER_REQUIRE(common_globals_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+uniform float pointSize;
+
+in vec2 u;
+in int flag;
+
+flat out vec4 finalColor;
+
+void main()
+{
+ vec3 world_pos = point_object_to_world(vec3(u, 0.0));
+ gl_Position = point_world_to_ndc(world_pos);
+
+ finalColor = ((flag & FACE_UV_SELECT) != 0) ? colorVertexSelect : vec4(colorWire.rgb, 1.0);
+ gl_PointSize = pointSize;
+}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_faces_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_faces_vert.glsl
new file mode 100644
index 00000000000..cf1018ae5f9
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_faces_vert.glsl
@@ -0,0 +1,22 @@
+#pragma BLENDER_REQUIRE(common_globals_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+uniform float uvOpacity;
+
+in vec2 u;
+in int flag;
+
+flat out vec4 finalColor;
+
+void main()
+{
+ vec3 world_pos = point_object_to_world(vec3(u, 0.0));
+ gl_Position = point_world_to_ndc(world_pos);
+
+ bool is_selected = (flag & FACE_UV_SELECT) != 0;
+ bool is_active = (flag & FACE_UV_ACTIVE) != 0;
+
+ finalColor = (is_selected) ? colorFaceSelect : colorFace;
+ finalColor = (is_active) ? colorEditMeshActive : finalColor;
+ finalColor.a *= uvOpacity;
+}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_stretching_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_stretching_vert.glsl
new file mode 100644
index 00000000000..ce97f1e27ac
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_stretching_vert.glsl
@@ -0,0 +1,98 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+uniform vec2 aspect;
+in vec2 pos;
+
+#ifdef STRETCH_ANGLE
+in vec2 uv_angles;
+in float angle;
+
+#else
+in float ratio;
+uniform float totalAreaRatio;
+uniform float totalAreaRatioInv;
+
+#endif
+
+noperspective out vec4 finalColor;
+
+vec3 weight_to_rgb(float weight)
+{
+ vec3 r_rgb;
+ float blend = ((weight / 2.0) + 0.5);
+
+ if (weight <= 0.25) { /* blue->cyan */
+ r_rgb[0] = 0.0;
+ r_rgb[1] = blend * weight * 4.0;
+ r_rgb[2] = blend;
+ }
+ else if (weight <= 0.50) { /* cyan->green */
+ r_rgb[0] = 0.0;
+ r_rgb[1] = blend;
+ r_rgb[2] = blend * (1.0 - ((weight - 0.25) * 4.0));
+ }
+ else if (weight <= 0.75) { /* green->yellow */
+ r_rgb[0] = blend * ((weight - 0.50) * 4.0);
+ r_rgb[1] = blend;
+ r_rgb[2] = 0.0;
+ }
+ else if (weight <= 1.0) { /* yellow->red */
+ r_rgb[0] = blend;
+ r_rgb[1] = blend * (1.0 - ((weight - 0.75) * 4.0));
+ r_rgb[2] = 0.0;
+ }
+ else {
+ /* exceptional value, unclamped or nan,
+ * avoid uninitialized memory use */
+ r_rgb[0] = 1.0;
+ r_rgb[1] = 0.0;
+ r_rgb[2] = 1.0;
+ }
+
+ return r_rgb;
+}
+
+#define M_PI 3.1415926535897932
+
+vec2 angle_to_v2(float angle)
+{
+ return vec2(cos(angle), sin(angle));
+}
+
+/* Adapted from BLI_math_vector.h */
+float angle_normalized_v2v2(vec2 v1, vec2 v2)
+{
+ v1 = normalize(v1 * aspect);
+ v2 = normalize(v2 * aspect);
+ /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
+ bool q = (dot(v1, v2) >= 0.0);
+ vec2 v = (q) ? (v1 - v2) : (v1 + v2);
+ float a = 2.0 * asin(length(v) / 2.0);
+ return (q) ? a : M_PI - a;
+}
+
+float area_ratio_to_stretch(float ratio, float tot_ratio, float inv_tot_ratio)
+{
+ ratio *= (ratio > 0.0f) ? tot_ratio : -inv_tot_ratio;
+ return (ratio > 1.0f) ? (1.0f / ratio) : ratio;
+}
+
+void main()
+{
+ vec3 world_pos = point_object_to_world(vec3(pos, 0.0));
+ gl_Position = point_world_to_ndc(world_pos);
+
+#ifdef STRETCH_ANGLE
+ vec2 v1 = angle_to_v2(uv_angles.x * M_PI);
+ vec2 v2 = angle_to_v2(uv_angles.y * M_PI);
+ float uv_angle = angle_normalized_v2v2(v1, v2) / M_PI;
+ float stretch = 1.0 - abs(uv_angle - angle);
+ stretch = stretch;
+ stretch = 1.0 - stretch * stretch;
+#else
+ float stretch = 1.0 - area_ratio_to_stretch(ratio, totalAreaRatio, totalAreaRatioInv);
+
+#endif
+
+ finalColor = vec4(weight_to_rgb(stretch), 1.0);
+}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_tiled_image_borders_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_tiled_image_borders_vert.glsl
new file mode 100644
index 00000000000..c762858a910
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_tiled_image_borders_vert.glsl
@@ -0,0 +1,12 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+in vec3 pos;
+
+void main()
+{
+ /* `pos` contains the coordinates of a quad (-1..1). but we need the coordinates of an image
+ * plane (0..1) */
+ vec3 image_pos = pos * 0.5 + 0.5;
+ vec4 position = point_object_to_ndc(image_pos);
+ gl_Position = position;
+}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_verts_frag.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_verts_frag.glsl
new file mode 100644
index 00000000000..11694de38ca
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_verts_frag.glsl
@@ -0,0 +1,33 @@
+
+uniform vec4 outlineColor;
+
+in vec4 radii;
+in vec4 fillColor;
+out vec4 fragColor;
+
+void main()
+{
+ float dist = length(gl_PointCoord - vec2(0.5));
+
+ // transparent outside of point
+ // --- 0 ---
+ // smooth transition
+ // --- 1 ---
+ // pure outline color
+ // --- 2 ---
+ // smooth transition
+ // --- 3 ---
+ // pure fill color
+ // ...
+ // dist = 0 at center of point
+
+ float midStroke = 0.5 * (radii[1] + radii[2]);
+
+ if (dist > midStroke) {
+ fragColor.rgb = outlineColor.rgb;
+ fragColor.a = mix(outlineColor.a, 0.0, smoothstep(radii[1], radii[0], dist));
+ }
+ else {
+ fragColor = mix(fillColor, outlineColor, smoothstep(radii[3], radii[2], dist));
+ }
+}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_verts_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_verts_vert.glsl
new file mode 100644
index 00000000000..327a35ce6b2
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_verts_vert.glsl
@@ -0,0 +1,44 @@
+#pragma BLENDER_REQUIRE(common_globals_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+uniform float pointSize;
+uniform float outlineWidth;
+
+in vec2 u;
+in int flag;
+
+out vec4 fillColor;
+out vec4 outlineColor;
+out vec4 radii;
+
+/* TODO Theme? */
+const vec4 pinned_col = vec4(1.0, 0.0, 0.0, 1.0);
+
+void main()
+{
+ bool is_selected = (flag & (VERT_UV_SELECT | FACE_UV_SELECT)) != 0;
+ bool is_pinned = (flag & VERT_UV_PINNED) != 0;
+ vec4 deselect_col = (is_pinned) ? pinned_col : vec4(colorWire.rgb, 1.0);
+ fillColor = (is_selected) ? colorVertexSelect : deselect_col;
+ outlineColor = (is_pinned) ? pinned_col : vec4(fillColor.rgb, 0.0);
+
+ vec3 world_pos = point_object_to_world(vec3(u, 0.0));
+ /* Move selected vertices to the top
+ * Vertices are between 0.0 and 0.2, Edges between 0.2 and 0.4
+ * actual pixels are at 0.75, 1.0 is used for the background. */
+ float depth = is_selected ? 0.05 : 0.15;
+ gl_Position = vec4(point_world_to_ndc(world_pos).xy, depth, 1.0);
+ gl_PointSize = pointSize;
+
+ // calculate concentric radii in pixels
+ float radius = 0.5 * pointSize;
+
+ // start at the outside and progress toward the center
+ radii[0] = radius;
+ radii[1] = radius - 1.0;
+ radii[2] = radius - outlineWidth;
+ radii[3] = radius - outlineWidth - 1.0;
+
+ // convert to PointCoord units
+ radii /= pointSize;
+}
diff --git a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl b/source/blender/draw/engines/overlay/shaders/grid_vert.glsl
index dd0e771ad93..6df4ead9f2a 100644
--- a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/grid_vert.glsl
@@ -12,7 +12,7 @@ uniform int gridFlag;
#define PLANE_YZ (1 << 6)
#define CLIP_Z_POS (1 << 7)
#define CLIP_Z_NEG (1 << 8)
-
+#define PLANE_IMAGE (1 << 11)
in vec3 pos;
out vec3 local_pos;
@@ -28,9 +28,12 @@ void main()
else if ((gridFlag & PLANE_XZ) != 0) {
vert_pos = vec3(pos.x, 0.0, pos.y);
}
- else {
+ else if ((gridFlag & PLANE_YZ) != 0) {
vert_pos = vec3(0.0, pos.x, pos.y);
}
+ else /* PLANE_IMAGE */ {
+ vert_pos = vec3(pos.xy * 0.5 + 0.5, 0.0);
+ }
local_pos = vert_pos;
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index e154a52b32f..30c6f0ad4dc 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -557,6 +557,9 @@ void DRW_shgroup_uniform_ivec4(DRWShadingGroup *shgroup,
int arraysize);
void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const float (*value)[3]);
void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float (*value)[4]);
+/* Only to be used when image load store is supported (GPU_shader_image_load_store_support()). */
+void DRW_shgroup_uniform_image(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex);
+void DRW_shgroup_uniform_image_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex);
/* Store value instead of referencing it. */
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value);
void DRW_shgroup_uniform_ivec2_copy(DRWShadingGroup *shgroup, const char *name, const int *value);
@@ -736,9 +739,11 @@ 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)' */
+
+ struct ARegion *region; /* 'CTX_wm_region(C)' */
+ struct RegionView3D *rv3d; /* 'CTX_wm_region_view3d(C)' */
+ struct View3D *v3d; /* 'CTX_wm_view3d(C)' */
+ struct SpaceLink *space_data; /* 'CTX_wm_space_data(C)' */
struct Scene *scene; /* 'CTX_data_scene(C)' */
struct ViewLayer *view_layer; /* 'CTX_data_view_layer(C)' */
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index ea5421f3965..56f31a69396 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -178,6 +178,9 @@ void DRW_globals_update(void)
UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, gb->colorOutline);
UI_GetThemeColorShadeAlpha4fv(TH_LIGHT, 0, 255, gb->colorLightNoAlpha);
+ /* UV colors */
+ UI_GetThemeColor4fv(TH_UV_SHADOW, gb->colorUVShadow);
+
gb->sizePixel = U.pixelsize;
gb->sizeObjectCenter = (UI_GetThemeValuef(TH_OBCENTER_DIA) + 1.0f) * U.pixelsize;
gb->sizeLightCenter = (UI_GetThemeValuef(TH_OBCENTER_DIA) + 1.5f) * U.pixelsize;
@@ -210,7 +213,7 @@ void DRW_globals_update(void)
/* TODO more accurate transform. */
srgb_to_linearrgb_v4(color, color);
color += 4;
- } while (color != gb->UBO_LAST_COLOR);
+ } while (color <= gb->UBO_LAST_COLOR);
}
if (G_draw.block_ubo == NULL) {
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index 645848e7fe0..e3967678319 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -33,7 +33,7 @@ struct RegionView3D;
struct ViewLayer;
#define UBO_FIRST_COLOR colorWire
-#define UBO_LAST_COLOR colorFaceFront
+#define UBO_LAST_COLOR colorUVShadow
/* Used as ubo but colors can be directly referenced as well */
/* Keep in sync with: common_globals_lib.glsl (globalsBlock) */
@@ -141,6 +141,8 @@ typedef struct GlobalsUboStorage {
float colorFaceBack[4];
float colorFaceFront[4];
+ float colorUVShadow[4];
+
/* NOTE! Put all color before UBO_LAST_COLOR */
float screenVecs[2][4]; /* padded as vec4 */
float sizeViewport[2], sizeViewportInv[2]; /* packed as vec4 in glsl */
diff --git a/source/blender/draw/intern/draw_fluid.c b/source/blender/draw/intern/draw_fluid.c
index af14f11e6e9..809512bd7dd 100644
--- a/source/blender/draw/intern/draw_fluid.c
+++ b/source/blender/draw/intern/draw_fluid.c
@@ -183,6 +183,10 @@ static GPUTexture *create_volume_texture(const int dim[3],
GPUTexture *tex = NULL;
int final_dim[3] = {UNPACK3(dim)};
+ if (data == NULL) {
+ return NULL;
+ }
+
while (1) {
tex = GPU_texture_create_3d("volume", UNPACK3(final_dim), 1, format, NULL);
@@ -292,6 +296,10 @@ static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres)
data = manta_smoke_get_density(fds->fluid);
}
+ if (data == NULL) {
+ return NULL;
+ }
+
GPUTexture *tex = create_volume_texture(dim, GPU_R8, data);
swizzle_texture_channel_single(tex);
return tex;
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index 9b503e00b36..cc0aa09ed97 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -346,10 +346,10 @@ void DRW_hair_update(void)
GPU_framebuffer_read_color(fb, 0, 0, width, height, 4, 0, GPU_DATA_FLOAT, data);
/* Upload back to VBO. */
GPU_vertbuf_use(pr_call->vbo);
- glBufferSubData(GL_ARRAY_BUFFER,
- sizeof(float[4]) * g_tf_id_offset,
- sizeof(float[4]) * max_read_px_len,
- data);
+ GPU_vertbuf_update_sub(pr_call->vbo,
+ sizeof(float[4]) * g_tf_id_offset,
+ sizeof(float[4]) * max_read_px_len,
+ data);
g_tf_id_offset += max_read_px_len;
pr_call->vert_len -= max_read_px_len;
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index e6d51bce54e..834505ca349 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -78,6 +78,7 @@
#include "RE_pipeline.h"
#include "UI_resources.h"
+#include "UI_view2d.h"
#include "WM_api.h"
#include "wm_window.h"
@@ -94,6 +95,7 @@
#include "engines/eevee/eevee_engine.h"
#include "engines/external/external_engine.h"
#include "engines/gpencil/gpencil_engine.h"
+#include "engines/image/image_engine.h"
#include "engines/overlay/overlay_engine.h"
#include "engines/select/select_engine.h"
#include "engines/workbench/workbench_engine.h"
@@ -126,6 +128,25 @@ static void drw_state_ensure_not_reused(DRWManager *dst)
}
#endif
+static bool drw_draw_show_annotation(void)
+{
+ if (DST.draw_ctx.space_data == NULL) {
+ View3D *v3d = DST.draw_ctx.v3d;
+ return (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) &&
+ ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0));
+ }
+
+ switch (DST.draw_ctx.space_data->spacetype) {
+ case SPACE_IMAGE: {
+ SpaceImage *sima = (SpaceImage *)DST.draw_ctx.space_data;
+ return (sima->flag & SI_SHOW_GPENCIL) != 0;
+ }
+ default:
+ BLI_assert("");
+ return false;
+ }
+}
+
/* -------------------------------------------------------------------- */
/** \name Threading
* \{ */
@@ -287,6 +308,7 @@ struct DupliObject *DRW_object_get_dupli(const Object *UNUSED(ob))
/** \name Color Management
* \{ */
+/* TODO(fclem) This should be a render engine callback to determine if we need CM or not. */
static void drw_viewport_colormanagement_set(void)
{
Scene *scene = DST.draw_ctx.scene;
@@ -296,21 +318,43 @@ static void drw_viewport_colormanagement_set(void)
ColorManagedViewSettings view_settings;
float dither = 0.0f;
- /* TODO(fclem) This should be a render engine callback to determine if we need CM or not. */
- bool use_workbench = BKE_scene_uses_blender_workbench(scene);
-
- bool use_scene_lights = (!v3d ||
- ((v3d->shading.type == OB_MATERIAL) &&
- (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS)) ||
- ((v3d->shading.type == OB_RENDER) &&
- (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS_RENDER)));
- bool use_scene_world =
- (!v3d ||
- ((v3d->shading.type == OB_MATERIAL) && (v3d->shading.flag & V3D_SHADING_SCENE_WORLD)) ||
- ((v3d->shading.type == OB_RENDER) && (v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER)));
- bool use_view_transform = v3d && (v3d->shading.type >= OB_MATERIAL);
- bool use_render_settings = v3d && ((use_workbench && use_view_transform) || use_scene_lights ||
- use_scene_world);
+ bool use_render_settings = false;
+ bool use_view_transform = false;
+
+ if (v3d) {
+ bool use_workbench = BKE_scene_uses_blender_workbench(scene);
+
+ bool use_scene_lights = (!v3d ||
+ ((v3d->shading.type == OB_MATERIAL) &&
+ (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS)) ||
+ ((v3d->shading.type == OB_RENDER) &&
+ (v3d->shading.flag & V3D_SHADING_SCENE_LIGHTS_RENDER)));
+ bool use_scene_world = (!v3d ||
+ ((v3d->shading.type == OB_MATERIAL) &&
+ (v3d->shading.flag & V3D_SHADING_SCENE_WORLD)) ||
+ ((v3d->shading.type == OB_RENDER) &&
+ (v3d->shading.flag & V3D_SHADING_SCENE_WORLD_RENDER)));
+ use_view_transform = v3d && (v3d->shading.type >= OB_MATERIAL);
+ use_render_settings = v3d && ((use_workbench && use_view_transform) || use_scene_lights ||
+ use_scene_world);
+ }
+ else if (DST.draw_ctx.space_data && DST.draw_ctx.space_data->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)DST.draw_ctx.space_data;
+ Image *image = sima->image;
+
+ /* Use inverse logic as there isn't a setting for `Color And Alpha`. */
+ const eSpaceImage_Flag display_channels_mode = sima->flag;
+ const bool display_color_channel = (display_channels_mode & (SI_SHOW_ALPHA | SI_SHOW_ZBUF)) ==
+ 0;
+ if (display_color_channel && image && (image->source != IMA_SRC_GENERATED) &&
+ ((image->flag & IMA_VIEW_AS_RENDER) != 0)) {
+ use_render_settings = true;
+ }
+ }
+ else {
+ use_render_settings = true;
+ use_view_transform = false;
+ }
if (use_render_settings) {
/* Use full render settings, for renders with scene lighting. */
@@ -495,6 +539,8 @@ static void draw_unit_state_create(void)
static void drw_viewport_var_init(void)
{
RegionView3D *rv3d = DST.draw_ctx.rv3d;
+ ARegion *region = DST.draw_ctx.region;
+
/* Refresh DST.size */
if (DST.viewport) {
int size[2];
@@ -585,6 +631,24 @@ static void drw_viewport_var_init(void)
DST.view_active = DST.view_default;
DST.view_previous = NULL;
}
+ else if (region) {
+ View2D *v2d = &region->v2d;
+ float viewmat[4][4];
+ float winmat[4][4];
+
+ rctf region_space = {0.0f, 1.0f, 0.0f, 1.0f};
+ BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, &region_space, viewmat);
+
+ unit_m4(winmat);
+ winmat[0][0] = 2.0f;
+ winmat[1][1] = 2.0f;
+ winmat[3][0] = -1.0f;
+ winmat[3][1] = -1.0f;
+
+ DST.view_default = DRW_view_create(viewmat, winmat, NULL, NULL, NULL);
+ DST.view_active = DST.view_default;
+ DST.view_previous = NULL;
+ }
else {
zero_v3(DST.screenvecs[0]);
zero_v3(DST.screenvecs[1]);
@@ -596,7 +660,7 @@ static void drw_viewport_var_init(void)
}
/* fclem: Is this still needed ? */
- if (DST.draw_ctx.object_edit) {
+ if (DST.draw_ctx.object_edit && rv3d) {
ED_view3d_init_mats_rv3d(DST.draw_ctx.object_edit, rv3d);
}
@@ -1163,6 +1227,19 @@ static void drw_engines_enable_basic(void)
use_drw_engine(&draw_engine_basic_type);
}
+static void drw_engines_enable_editors(void)
+{
+ SpaceLink *space_data = DST.draw_ctx.space_data;
+ if (!space_data) {
+ return;
+ }
+
+ if (space_data->spacetype == SPACE_IMAGE) {
+ use_drw_engine(&draw_engine_image_type);
+ use_drw_engine(&draw_engine_overlay_type);
+ }
+}
+
static void drw_engines_enable(ViewLayer *UNUSED(view_layer),
RenderEngineType *engine_type,
bool gpencil_engine_needed)
@@ -1288,6 +1365,8 @@ void DRW_draw_callbacks_pre_scene(void)
if (DST.draw_ctx.evil_C) {
ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.region, REGION_DRAW_PRE_VIEW);
+ /* Callback can be nasty and do whatever they want with the state.
+ * Don't trust them! */
DRW_state_reset();
}
}
@@ -1299,8 +1378,7 @@ void DRW_draw_callbacks_post_scene(void)
View3D *v3d = DST.draw_ctx.v3d;
Depsgraph *depsgraph = DST.draw_ctx.depsgraph;
- const bool do_annotations = (v3d && ((v3d->flag2 & V3D_SHOW_ANNOTATION) != 0) &&
- ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0));
+ const bool do_annotations = drw_draw_show_annotation();
if (DST.draw_ctx.evil_C) {
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
@@ -1324,6 +1402,9 @@ void DRW_draw_callbacks_post_scene(void)
drw_debug_draw();
GPU_depth_test(GPU_DEPTH_NONE);
+ /* Apply state for callbacks. */
+ GPU_apply_state();
+
ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.region, REGION_DRAW_POST_VIEW);
/* Callback can be nasty and do whatever they want with the state.
@@ -1387,21 +1468,30 @@ struct DRWTextStore *DRW_text_cache_ensure(void)
* for each relevant engine / mode engine. */
void DRW_draw_view(const bContext *C)
{
- Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
- ARegion *region = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
- Scene *scene = DEG_get_evaluated_scene(depsgraph);
- RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
- GPUViewport *viewport = WM_draw_region_get_bound_viewport(region);
+ if (v3d) {
+ Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
+ ARegion *region = CTX_wm_region(C);
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type);
+ GPUViewport *viewport = WM_draw_region_get_bound_viewport(region);
- /* Reset before using it. */
- drw_state_prepare_clean_for_draw(&DST);
- DST.options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 &&
- (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0);
- DST.options.draw_background = (scene->r.alphamode == R_ADDSKY) ||
- (v3d->shading.type != OB_RENDER);
- DST.options.do_color_management = true;
- DRW_draw_render_loop_ex(depsgraph, engine_type, region, v3d, viewport, C);
+ /* Reset before using it. */
+ drw_state_prepare_clean_for_draw(&DST);
+ DST.options.draw_text = ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0 &&
+ (v3d->overlay.flag & V3D_OVERLAY_HIDE_TEXT) != 0);
+ DST.options.draw_background = (scene->r.alphamode == R_ADDSKY) ||
+ (v3d->shading.type != OB_RENDER);
+ DST.options.do_color_management = true;
+ DRW_draw_render_loop_ex(depsgraph, engine_type, region, v3d, viewport, C);
+ }
+ else {
+ Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
+ ARegion *ar = CTX_wm_region(C);
+ GPUViewport *viewport = WM_draw_region_get_bound_viewport(ar);
+ drw_state_prepare_clean_for_draw(&DST);
+ DRW_draw_render_loop_2d_ex(depsgraph, ar, viewport, C);
+ }
}
/**
@@ -1909,6 +1999,171 @@ void DRW_cache_restart(void)
copy_v2_v2(DST.inv_size, inv_size);
}
+void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph,
+ ARegion *region,
+ GPUViewport *viewport,
+ const bContext *evil_C)
+{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
+
+ DST.draw_ctx.evil_C = evil_C;
+ DST.viewport = viewport;
+
+ /* Setup viewport */
+ DST.draw_ctx = (DRWContextState){
+ .region = region,
+ .scene = scene,
+ .view_layer = view_layer,
+ .obact = OBACT(view_layer),
+ .depsgraph = depsgraph,
+ .space_data = CTX_wm_space_data(evil_C),
+
+ /* reuse if caller sets */
+ .evil_C = DST.draw_ctx.evil_C,
+ };
+
+ drw_context_state_init();
+ drw_viewport_var_init();
+ drw_viewport_colormanagement_set();
+
+ /* TODO(jbakker): Only populate when editor needs to draw object.
+ * for the image editor this is when showing UV's.*/
+ const bool do_populate_loop = true;
+ const bool do_annotations = drw_draw_show_annotation();
+
+ /* Get list of enabled engines */
+ drw_engines_enable_editors();
+ drw_engines_data_validate();
+
+ /* Update ubos */
+ DRW_globals_update();
+
+ drw_debug_init();
+
+ /* No framebuffer allowed before drawing. */
+ BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get());
+ GPU_framebuffer_bind(DST.default_framebuffer);
+ GPU_framebuffer_clear_depth_stencil(DST.default_framebuffer, 1.0f, 0xFF);
+
+ /* Init engines */
+ drw_engines_init();
+ drw_task_graph_init();
+
+ /* Cache filling */
+ {
+ PROFILE_START(stime);
+ drw_engines_cache_init();
+
+ /* Only iterate over objects when overlay uses object data. */
+ if (do_populate_loop) {
+ DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) {
+ drw_engines_cache_populate(ob);
+ }
+ DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END;
+ }
+
+ drw_engines_cache_finish();
+
+ DRW_render_instance_buffer_finish();
+
+#ifdef USE_PROFILE
+ double *cache_time = GPU_viewport_cache_time_get(DST.viewport);
+ PROFILE_END_UPDATE(*cache_time, stime);
+#endif
+ }
+ drw_task_graph_deinit();
+
+ DRW_stats_begin();
+
+ GPU_framebuffer_bind(DST.default_framebuffer);
+
+ /* Start Drawing */
+ DRW_state_reset();
+
+ if (DST.draw_ctx.evil_C) {
+ ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.region, REGION_DRAW_PRE_VIEW);
+ }
+
+ drw_engines_draw_scene();
+
+ /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */
+ GPU_flush();
+
+ if (DST.draw_ctx.evil_C) {
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ DRW_state_reset();
+
+ GPU_framebuffer_bind(dfbl->overlay_fb);
+
+ if (do_annotations) {
+ GPU_depth_test(false);
+ GPU_matrix_push_projection();
+ wmOrtho2(
+ region->v2d.cur.xmin, region->v2d.cur.xmax, region->v2d.cur.ymin, region->v2d.cur.ymax);
+ ED_annotation_draw_view2d(DST.draw_ctx.evil_C, true);
+ GPU_matrix_pop_projection();
+
+ GPU_depth_test(true);
+ }
+
+ GPU_depth_test(false);
+ ED_region_draw_cb_draw(DST.draw_ctx.evil_C, DST.draw_ctx.region, REGION_DRAW_POST_VIEW);
+ GPU_depth_test(true);
+ /* Callback can be nasty and do whatever they want with the state.
+ * Don't trust them! */
+ DRW_state_reset();
+
+ GPU_depth_test(false);
+ drw_engines_draw_text();
+ GPU_depth_test(true);
+
+ if (do_annotations) {
+ GPU_depth_test(false);
+ ED_annotation_draw_view2d(DST.draw_ctx.evil_C, false);
+ GPU_depth_test(true);
+ }
+ }
+
+ DRW_draw_cursor_2d();
+ ED_region_pixelspace(DST.draw_ctx.region);
+
+ {
+ GPU_depth_test(false);
+ DRW_draw_gizmo_2d();
+ GPU_depth_test(true);
+ }
+
+ DRW_stats_reset();
+
+ if (G.debug_value > 20 && G.debug_value < 30) {
+ GPU_depth_test(false);
+ /* local coordinate visible rect inside region, to accommodate overlapping ui */
+ const rcti *rect = ED_region_visible_rect(DST.draw_ctx.region);
+ DRW_stats_draw(rect);
+ GPU_depth_test(true);
+ }
+
+ if (WM_draw_region_get_bound_viewport(region)) {
+ /* Don't unbind the framebuffer yet in this case and let
+ * GPU_viewport_unbind do it, so that we can still do further
+ * drawing of action zones on top. */
+ }
+ else {
+ GPU_framebuffer_restore();
+ }
+
+ DRW_state_reset();
+ drw_engines_disable();
+
+ drw_viewport_cache_resize();
+
+#ifdef DEBUG
+ /* Avoid accidental reuse. */
+ drw_state_ensure_not_reused(&DST);
+#endif
+}
+
static struct DRWSelectBuffer {
struct GPUFrameBuffer *framebuffer_depth_only;
struct GPUTexture *texture_depth;
@@ -2637,6 +2892,8 @@ void DRW_engines_register(void)
DRW_engine_register(&draw_engine_select_type);
DRW_engine_register(&draw_engine_basic_type);
+ DRW_engine_register(&draw_engine_image_type);
+
/* setup callbacks */
{
BKE_mball_batch_cache_dirty_tag_cb = DRW_mball_batch_cache_dirty_tag;
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index c0bcb0e679f..9f6a970ea22 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -278,6 +278,8 @@ typedef enum {
DRW_UNIFORM_FLOAT_COPY,
DRW_UNIFORM_TEXTURE,
DRW_UNIFORM_TEXTURE_REF,
+ DRW_UNIFORM_IMAGE,
+ DRW_UNIFORM_IMAGE_REF,
DRW_UNIFORM_BLOCK,
DRW_UNIFORM_BLOCK_REF,
DRW_UNIFORM_TFEEDBACK_TARGET,
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index a4fc44e9571..81842f5d2ec 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -199,10 +199,12 @@ static void drw_shgroup_uniform_create_ex(DRWShadingGroup *shgroup,
case DRW_UNIFORM_BLOCK_REF:
uni->block_ref = (GPUUniformBuf **)value;
break;
+ case DRW_UNIFORM_IMAGE:
case DRW_UNIFORM_TEXTURE:
uni->texture = (GPUTexture *)value;
uni->sampler_state = sampler_state;
break;
+ case DRW_UNIFORM_IMAGE_REF:
case DRW_UNIFORM_TEXTURE_REF:
uni->texture_ref = (GPUTexture **)value;
uni->sampler_state = sampler_state;
@@ -261,6 +263,20 @@ void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name,
DRW_shgroup_uniform_texture_ref_ex(shgroup, name, tex, GPU_SAMPLER_MAX);
}
+void DRW_shgroup_uniform_image(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
+{
+ BLI_assert(tex != NULL);
+ int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
+ drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_IMAGE, tex, 0, 0, 1);
+}
+
+void DRW_shgroup_uniform_image_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
+{
+ BLI_assert(tex != NULL);
+ int loc = GPU_shader_get_texture_binding(shgroup->shader, name);
+ drw_shgroup_uniform_create_ex(shgroup, loc, DRW_UNIFORM_IMAGE_REF, tex, 0, 0, 1);
+}
+
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup,
const char *name,
const GPUUniformBuf *ubo)
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 79d74e1f67d..84f618c1c15 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -596,6 +596,12 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup,
case DRW_UNIFORM_TEXTURE_REF:
GPU_texture_bind_ex(*uni->texture_ref, uni->sampler_state, uni->location, false);
break;
+ case DRW_UNIFORM_IMAGE:
+ GPU_texture_image_bind(uni->texture, uni->location);
+ break;
+ case DRW_UNIFORM_IMAGE_REF:
+ GPU_texture_image_bind(*uni->texture_ref, uni->location);
+ break;
case DRW_UNIFORM_BLOCK:
GPU_uniformbuf_bind(uni->block, uni->location);
break;
diff --git a/source/blender/draw/intern/draw_manager_profiling.c b/source/blender/draw/intern/draw_manager_profiling.c
index 57887c11c02..f8587555480 100644
--- a/source/blender/draw/intern/draw_manager_profiling.c
+++ b/source/blender/draw/intern/draw_manager_profiling.c
@@ -44,8 +44,8 @@
#define GPU_TIMER_FALLOFF 0.1
typedef struct DRWTimer {
- GLuint query[2];
- GLuint64 time_average;
+ uint32_t query[2];
+ uint64_t time_average;
char name[MAX_TIMER_NAME];
int lvl; /* Hierarchy level for nested timer. */
bool is_query; /* Does this timer actually perform queries or is it just a group. */
@@ -64,10 +64,10 @@ static struct DRWTimerPool {
void DRW_stats_free(void)
{
if (DTP.timers != NULL) {
- for (int i = 0; i < DTP.timer_count; i++) {
- DRWTimer *timer = &DTP.timers[i];
- glDeleteQueries(2, timer->query);
- }
+ // for (int i = 0; i < DTP.timer_count; i++) {
+ // DRWTimer *timer = &DTP.timers[i];
+ // glDeleteQueries(2, timer->query);
+ // }
MEM_freeN(DTP.timers);
DTP.timers = NULL;
}
@@ -117,12 +117,12 @@ static void drw_stats_timer_start_ex(const char *name, const bool is_query)
BLI_assert(!DTP.is_querying);
if (timer->is_query) {
if (timer->query[0] == 0) {
- glGenQueries(1, timer->query);
+ // glGenQueries(1, timer->query);
}
- glFinish();
+ // glFinish();
/* Issue query for the next frame */
- glBeginQuery(GL_TIME_ELAPSED, timer->query[0]);
+ // glBeginQuery(GL_TIME_ELAPSED, timer->query[0]);
DTP.is_querying = true;
}
}
@@ -154,7 +154,7 @@ void DRW_stats_query_end(void)
if (DTP.is_recording) {
DTP.end_increment++;
BLI_assert(DTP.is_querying);
- glEndQuery(GL_TIME_ELAPSED);
+ // glEndQuery(GL_TIME_ELAPSED);
DTP.is_querying = false;
}
}
@@ -167,19 +167,19 @@ void DRW_stats_reset(void)
"You forgot a DRW_stats_group/query_start somewhere!");
if (DTP.is_recording) {
- GLuint64 lvl_time[MAX_NESTED_TIMER] = {0};
+ uint64_t lvl_time[MAX_NESTED_TIMER] = {0};
/* Swap queries for the next frame and sum up each lvl time. */
for (int i = DTP.timer_increment - 1; i >= 0; i--) {
DRWTimer *timer = &DTP.timers[i];
- SWAP(GLuint, timer->query[0], timer->query[1]);
+ SWAP(uint32_t, timer->query[0], timer->query[1]);
BLI_assert(timer->lvl < MAX_NESTED_TIMER);
if (timer->is_query) {
- GLuint64 time;
+ uint64_t time = 0;
if (timer->query[0] != 0) {
- glGetQueryObjectui64v(timer->query[0], GL_QUERY_RESULT, &time);
+ // glGetQueryObjectui64v(timer->query[0], GL_QUERY_RESULT, &time);
}
else {
time = 1000000000; /* 1ms default */
diff --git a/source/blender/draw/intern/draw_manager_text.c b/source/blender/draw/intern/draw_manager_text.c
index adcac15ab85..e3d0dab6767 100644
--- a/source/blender/draw/intern/draw_manager_text.c
+++ b/source/blender/draw/intern/draw_manager_text.c
@@ -24,6 +24,7 @@
#include "BLI_math.h"
#include "BLI_memiter.h"
+#include "BLI_rect.h"
#include "BLI_string.h"
#include "BKE_editmesh.h"
@@ -122,76 +123,105 @@ void DRW_text_cache_add(DRWTextStore *dt,
}
}
-void DRW_text_cache_draw(DRWTextStore *dt, ARegion *region, struct View3D *v3d)
+static void drw_text_cache_draw_ex(DRWTextStore *dt, ARegion *region)
{
- RegionView3D *rv3d = region->regiondata;
ViewCachedString *vos;
- int tot = 0;
-
- /* project first and test */
BLI_memiter_handle it;
- BLI_memiter_iter_init(dt->cache_strings, &it);
- while ((vos = BLI_memiter_iter_step(&it))) {
- if (ED_view3d_project_short_ex(
- region,
- (vos->flag & DRW_TEXT_CACHE_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
- (vos->flag & DRW_TEXT_CACHE_LOCALCLIP) != 0,
- vos->vec,
- vos->sco,
- V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) ==
- V3D_PROJ_RET_OK) {
- tot++;
- }
- else {
- vos->sco[0] = IS_CLIPPED;
- }
- }
+ int col_pack_prev = 0;
- if (tot) {
- int col_pack_prev = 0;
+ float original_proj[4][4];
+ GPU_matrix_projection_get(original_proj);
+ wmOrtho2_region_pixelspace(region);
- /* Disable clipping for text */
- if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
- GPU_clip_distances(0);
- }
+ GPU_matrix_push();
+ GPU_matrix_identity_set();
- float original_proj[4][4];
- GPU_matrix_projection_get(original_proj);
- wmOrtho2_region_pixelspace(region);
+ const int font_id = BLF_default();
- GPU_matrix_push();
- GPU_matrix_identity_set();
+ const uiStyle *style = UI_style_get();
- const int font_id = BLF_default();
+ BLF_size(font_id, style->widget.points * U.pixelsize, U.dpi);
- const uiStyle *style = UI_style_get();
+ BLI_memiter_iter_init(dt->cache_strings, &it);
+ while ((vos = BLI_memiter_iter_step(&it))) {
+ if (vos->sco[0] != IS_CLIPPED) {
+ if (col_pack_prev != vos->col.pack) {
+ BLF_color4ubv(font_id, vos->col.ub);
+ col_pack_prev = vos->col.pack;
+ }
+
+ BLF_position(
+ font_id, (float)(vos->sco[0] + vos->xoffs), (float)(vos->sco[1] + vos->yoffs), 2.0f);
+
+ ((vos->flag & DRW_TEXT_CACHE_ASCII) ? BLF_draw_ascii : BLF_draw)(
+ font_id,
+ (vos->flag & DRW_TEXT_CACHE_STRING_PTR) ? *((const char **)vos->str) : vos->str,
+ vos->str_len);
+ }
+ }
- BLF_size(font_id, style->widget.points * U.pixelsize, U.dpi);
+ GPU_matrix_pop();
+ GPU_matrix_projection_set(original_proj);
+}
+void DRW_text_cache_draw(DRWTextStore *dt, ARegion *region, struct View3D *v3d)
+{
+ ViewCachedString *vos;
+ if (v3d) {
+ RegionView3D *rv3d = region->regiondata;
+ int tot = 0;
+ /* project first and test */
+ BLI_memiter_handle it;
BLI_memiter_iter_init(dt->cache_strings, &it);
while ((vos = BLI_memiter_iter_step(&it))) {
- if (vos->sco[0] != IS_CLIPPED) {
- if (col_pack_prev != vos->col.pack) {
- BLF_color4ubv(font_id, vos->col.ub);
- col_pack_prev = vos->col.pack;
- }
+ if (ED_view3d_project_short_ex(
+ region,
+ (vos->flag & DRW_TEXT_CACHE_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
+ (vos->flag & DRW_TEXT_CACHE_LOCALCLIP) != 0,
+ vos->vec,
+ vos->sco,
+ V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) ==
+ V3D_PROJ_RET_OK) {
+ tot++;
+ }
+ else {
+ vos->sco[0] = IS_CLIPPED;
+ }
+ }
- BLF_position(
- font_id, (float)(vos->sco[0] + vos->xoffs), (float)(vos->sco[1] + vos->yoffs), 2.0f);
+ if (tot) {
+ /* Disable clipping for text */
+ const bool rv3d_clipping_enabled = RV3D_CLIPPING_ENABLED(v3d, rv3d);
+ if (rv3d_clipping_enabled) {
+ GPU_clip_distances(0);
+ }
+
+ drw_text_cache_draw_ex(dt, region);
- ((vos->flag & DRW_TEXT_CACHE_ASCII) ? BLF_draw_ascii : BLF_draw)(
- font_id,
- (vos->flag & DRW_TEXT_CACHE_STRING_PTR) ? *((const char **)vos->str) : vos->str,
- vos->str_len);
+ if (rv3d_clipping_enabled) {
+ GPU_clip_distances(6);
}
}
+ }
+ else {
+ /* project first */
+ BLI_memiter_handle it;
+ BLI_memiter_iter_init(dt->cache_strings, &it);
+ View2D *v2d = &region->v2d;
+ float viewmat[4][4];
+ rctf region_space = {0.0f, region->winx, 0.0f, region->winy};
+ BLI_rctf_transform_calc_m4_pivot_min(&v2d->cur, &region_space, viewmat);
- GPU_matrix_pop();
- GPU_matrix_projection_set(original_proj);
+ while ((vos = BLI_memiter_iter_step(&it))) {
+ float p[3];
+ copy_v3_v3(p, vos->vec);
+ mul_m4_v3(viewmat, p);
- if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
- GPU_clip_distances(6);
+ vos->sco[0] = p[0];
+ vos->sco[1] = p[1];
}
+
+ drw_text_cache_draw_ex(dt, region);
}
}
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index d01e1a51080..3033cf70b29 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -35,6 +35,7 @@
#include "GPU_shader.h"
#include "UI_resources.h"
+#include "UI_view2d.h"
#include "WM_types.h"
@@ -196,6 +197,65 @@ void DRW_draw_cursor(void)
}
}
+/* -------------------------------------------------------------------- */
+
+/** \name 2D Cursor
+ * \{ */
+
+static bool is_cursor_visible_2d(const DRWContextState *draw_ctx)
+{
+ SpaceInfo *space_data = (SpaceInfo *)draw_ctx->space_data;
+ if (space_data == NULL) {
+ return false;
+ }
+ if (space_data->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
+ return sima->mode == SI_MODE_UV;
+ }
+ return false;
+}
+
+void DRW_draw_cursor_2d(void)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ARegion *region = draw_ctx->region;
+
+ GPU_color_mask(true, true, true, true);
+ GPU_depth_mask(false);
+ GPU_depth_test(GPU_DEPTH_NONE);
+
+ if (is_cursor_visible_2d(draw_ctx)) {
+ SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
+ int co[2];
+ UI_view2d_view_to_region(&region->v2d, sima->cursor[0], sima->cursor[1], &co[0], &co[1]);
+
+ /* Draw nice Anti Aliased cursor. */
+ GPU_line_width(1.0f);
+ GPU_blend(true);
+ GPU_line_smooth(true);
+
+ /* Draw lines */
+ float original_proj[4][4];
+ GPU_matrix_projection_get(original_proj);
+ GPU_matrix_push();
+ ED_region_pixelspace(region);
+ GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f);
+ GPU_matrix_scale_2f(U.widget_unit, U.widget_unit);
+
+ GPUBatch *cursor_batch = DRW_cache_cursor_get(true);
+ GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR);
+ GPU_batch_set_shader(cursor_batch, shader);
+
+ GPU_batch_draw(cursor_batch);
+
+ GPU_blend(false);
+ GPU_line_smooth(false);
+ GPU_matrix_pop();
+ GPU_matrix_projection_set(original_proj);
+ }
+}
+/* \} */
+
/* **************************** 3D Gizmo ******************************** */
void DRW_draw_gizmo_3d(void)
diff --git a/source/blender/draw/intern/draw_view.h b/source/blender/draw/intern/draw_view.h
index a01a2d0dcce..24fabaae05e 100644
--- a/source/blender/draw/intern/draw_view.h
+++ b/source/blender/draw/intern/draw_view.h
@@ -25,5 +25,6 @@
void DRW_draw_region_info(void);
void DRW_clear_background(void);
void DRW_draw_cursor(void);
+void DRW_draw_cursor_2d(void);
void DRW_draw_gizmo_3d(void);
void DRW_draw_gizmo_2d(void);
diff --git a/source/blender/draw/intern/shaders/common_globals_lib.glsl b/source/blender/draw/intern/shaders/common_globals_lib.glsl
index bd1b1fb6f3a..691f1d5e519 100644
--- a/source/blender/draw/intern/shaders/common_globals_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_globals_lib.glsl
@@ -103,6 +103,8 @@ layout(std140) uniform globalsBlock
vec4 colorFaceBack;
vec4 colorFaceFront;
+ vec4 colorUVShadow;
+
vec4 screenVecs[2];
vec4 sizeViewport; /* Inverted size in zw. */
diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc
index b73c94208b5..8feccc9588e 100644
--- a/source/blender/draw/tests/shaders_test.cc
+++ b/source/blender/draw/tests/shaders_test.cc
@@ -11,6 +11,7 @@
#include "engines/eevee/eevee_private.h"
#include "engines/gpencil/gpencil_engine.h"
+#include "engines/image/image_private.h"
#include "engines/overlay/overlay_private.h"
#include "engines/workbench/workbench_private.h"
@@ -151,8 +152,19 @@ TEST_F(DrawTest, gpencil_glsl_shaders)
GPENCIL_shader_free();
}
+TEST_F(DrawTest, image_glsl_shaders)
+{
+ IMAGE_shader_library_ensure();
+
+ EXPECT_NE(IMAGE_shader_image_get(), nullptr);
+
+ IMAGE_shader_free();
+}
+
TEST_F(DrawTest, overlay_glsl_shaders)
{
+ OVERLAY_shader_library_ensure();
+
for (int i = 0; i < 2; i++) {
eGPUShaderConfig sh_cfg = i == 0 ? GPU_SHADER_CFG_DEFAULT : GPU_SHADER_CFG_CLIPPED;
DRW_draw_state_init_gtests(sh_cfg);
@@ -189,6 +201,13 @@ TEST_F(DrawTest, overlay_glsl_shaders)
EXPECT_NE(OVERLAY_shader_edit_mesh_vert(), nullptr);
EXPECT_NE(OVERLAY_shader_edit_particle_strand(), nullptr);
EXPECT_NE(OVERLAY_shader_edit_particle_point(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_uv_edges_get(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_uv_face_get(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_uv_face_dots_get(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_uv_verts_get(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_uv_stretching_area_get(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_uv_stretching_angle_get(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_uv_tiled_image_borders_get(), nullptr);
EXPECT_NE(OVERLAY_shader_extra(false), nullptr);
EXPECT_NE(OVERLAY_shader_extra(true), nullptr);
EXPECT_NE(OVERLAY_shader_extra_groundline(), nullptr);
@@ -201,6 +220,7 @@ TEST_F(DrawTest, overlay_glsl_shaders)
EXPECT_NE(OVERLAY_shader_facing(), nullptr);
EXPECT_NE(OVERLAY_shader_gpencil_canvas(), nullptr);
EXPECT_NE(OVERLAY_shader_grid(), nullptr);
+ EXPECT_NE(OVERLAY_shader_grid_image(), nullptr);
EXPECT_NE(OVERLAY_shader_image(), nullptr);
EXPECT_NE(OVERLAY_shader_motion_path_line(), nullptr);
EXPECT_NE(OVERLAY_shader_motion_path_vert(), nullptr);
diff --git a/source/blender/editors/animation/CMakeLists.txt b/source/blender/editors/animation/CMakeLists.txt
index ce6778a1ff9..1ca9a844feb 100644
--- a/source/blender/editors/animation/CMakeLists.txt
+++ b/source/blender/editors/animation/CMakeLists.txt
@@ -30,9 +30,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
anim_channels_defines.c
@@ -69,6 +66,5 @@ if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_animation "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/armature/CMakeLists.txt b/source/blender/editors/armature/CMakeLists.txt
index 71c7febe192..98c050950be 100644
--- a/source/blender/editors/armature/CMakeLists.txt
+++ b/source/blender/editors/armature/CMakeLists.txt
@@ -31,10 +31,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
armature_add.c
armature_edit.c
@@ -67,6 +63,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_armature "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/curve/CMakeLists.txt b/source/blender/editors/curve/CMakeLists.txt
index ff80c47baa8..877c2d99102 100644
--- a/source/blender/editors/curve/CMakeLists.txt
+++ b/source/blender/editors/curve/CMakeLists.txt
@@ -31,10 +31,6 @@ set(INC
../../../../extern/curve_fit_nd
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
curve_ops.c
editcurve.c
@@ -59,6 +55,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_curve "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 2b3df79476a..e6815582a04 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -3640,9 +3640,8 @@ static void subdividenurb(Object *obedit, View3D *v3d, int number_cuts)
* degree of the functions used to build the NURB. The
* expression
*
- * degree = #knots - #controlpoints + 1 (J Walter piece)
- * degree = #knots - #controlpoints (Blender
- * implementation)
+ * `degree = knots - controlpoints + 1` (J Walter piece)
+ * `degree = knots - controlpoints` (Blender implementation)
* ( this is confusing.... what is true? Another concern
* is that the JW piece allows the curve to become
* explicitly 1st order derivative discontinuous, while
@@ -3651,12 +3650,12 @@ static void subdividenurb(Object *obedit, View3D *v3d, int number_cuts)
* is an invariant for a single NURB curve. Raising the degree
* of the NURB is done elsewhere; the degree is assumed
* constant during this operation. Degree is a property shared
- * by all controlpoints in a curve (even though it is stored
+ * by all control-points in a curve (even though it is stored
* per control point - this can be misleading).
* Adding a knot is done by searching for the place in the
* knot vector where a certain knot value must be inserted, or
* by picking an appropriate knot value between two existing
- * ones. The number of controlpoints that is influenced by the
+ * ones. The number of control-points that is influenced by the
* insertion depends on the order of the curve. A certain
* minimum number of knots is needed to form high-order
* curves, as can be seen from the equation above. In Blender,
diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c
index 19b05f0af0c..4d72e90b89b 100644
--- a/source/blender/editors/curve/editcurve_add.c
+++ b/source/blender/editors/curve/editcurve_add.c
@@ -508,7 +508,10 @@ Nurb *ED_curve_add_nurbs_primitive(
static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
{
- Object *obedit = CTX_data_edit_object(C);
+ struct Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
ListBase *editnurb;
Nurb *nu;
bool newob = false;
@@ -565,7 +568,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
/* userdef */
if (newob && !enter_editmode) {
- ED_object_editmode_exit(C, EM_FREEDATA);
+ ED_object_editmode_exit_ex(bmain, scene, obedit, EM_FREEDATA);
}
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
diff --git a/source/blender/editors/gizmo_library/CMakeLists.txt b/source/blender/editors/gizmo_library/CMakeLists.txt
index 1f3edf31b19..eeb1e60166b 100644
--- a/source/blender/editors/gizmo_library/CMakeLists.txt
+++ b/source/blender/editors/gizmo_library/CMakeLists.txt
@@ -32,10 +32,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
gizmo_draw_utils.c
gizmo_geometry.h
@@ -59,6 +55,5 @@ set(SRC
set(LIB
)
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_gizmo_library "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt
index 735ad8bc039..20408327105 100644
--- a/source/blender/editors/gpencil/CMakeLists.txt
+++ b/source/blender/editors/gpencil/CMakeLists.txt
@@ -31,10 +31,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
annotate_draw.c
annotate_paint.c
@@ -75,6 +71,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_gpencil "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index 47b8eb543f4..341f97943a5 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -150,6 +150,7 @@ int ED_file_extension_icon(const char *path);
void ED_file_read_bookmarks(void);
+void ED_file_change_dir_ex(struct bContext *C, struct bScreen *screen, struct ScrArea *area);
void ED_file_change_dir(struct bContext *C);
void ED_file_path_button(struct bScreen *screen,
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index f87db32a660..67422e4cfd4 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -2374,10 +2374,7 @@ uiPropertySplitWrapper uiItemPropertySplitWrapperCreate(uiLayout *parent_layout)
void uiItemL(uiLayout *layout, const char *name, int icon); /* label */
void uiItemL_ex(
uiLayout *layout, const char *name, int icon, const bool highlight, const bool redalert);
-uiBut *uiItemL_respect_property_split(uiLayout *layout,
- const char *text,
- int icon,
- uiLayout **r_layout);
+uiLayout *uiItemL_respect_property_split(uiLayout *layout, const char *text, int icon);
/* label icon for dragging */
void uiItemLDrag(uiLayout *layout, struct PointerRNA *ptr, const char *name, int icon);
/* menu */
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index e4fb0631f06..680cf3ea01a 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -34,10 +34,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
interface.c
interface_align.c
@@ -113,6 +109,5 @@ if(WIN32)
endif()
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_interface "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 8c564ecd1d4..b0530c797a8 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -6700,7 +6700,7 @@ static void operator_enum_search_update_fn(const struct bContext *C,
}
}
- MEM_freeN(filtered_items);
+ MEM_freeN((void *)filtered_items);
BLI_string_search_free(search);
if (do_free) {
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index c91b4d826a7..d22ddb5f2b7 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -256,7 +256,7 @@ static void def_internal_vicon(int icon_id, VectorDrawFunc drawFunc)
/* Utilities */
-static void viconutil_set_point(GLint pt[2], int x, int y)
+static void viconutil_set_point(int pt[2], int x, int y)
{
pt[0] = x;
pt[1] = y;
@@ -264,7 +264,7 @@ static void viconutil_set_point(GLint pt[2], int x, int y)
static void vicon_small_tri_right_draw(int x, int y, int w, int UNUSED(h), float alpha)
{
- GLint pts[3][2];
+ int pts[3][2];
const int cx = x + w / 2 - 4;
const int cy = y + w / 2;
const int d = w / 5, d2 = w / 7;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index a423f0705bb..ac5230c551a 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -275,14 +275,6 @@ struct uiBut {
uiButPushedStateFunc pushed_state_func;
void *pushed_state_arg;
- /**
- * Used for property search, so that a button's label and decorator can be filtered and
- * unfiltered along with it. Due to the sometimes arbitrary nature of which button to choose
- * for these values, they aren't always filled.
- */
- uiBut *label_but;
- uiBut *decorator_but;
-
/* pointer back */
uiBlock *block;
};
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index d46bca0ba48..79c560e0eff 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -80,6 +80,17 @@
/* uiLayoutRoot */
+/**
+ * A group of button references, used by property search to keep track of sets of buttons that
+ * should be searched together. For example, in property split layouts number buttons and their
+ * labels (and even their decorators) are separate buttons, but they must be searched and
+ * highlighted together.
+ */
+typedef struct uiButtonGroup {
+ void *next, *prev;
+ ListBase buttons; /* #LinkData with #uiBut data field. */
+} uiButtonGroup;
+
typedef struct uiLayoutRoot {
struct uiLayoutRoot *next, *prev;
@@ -93,6 +104,8 @@ typedef struct uiLayoutRoot {
*/
bool search_only;
+ ListBase button_groups; /* #uiButtonGroup. */
+
int emw, emh;
int padding;
@@ -227,8 +240,6 @@ typedef struct uiLayoutItemRoot {
/** \} */
-static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon);
-
/* -------------------------------------------------------------------- */
/** \name Item
* \{ */
@@ -424,6 +435,43 @@ static void ui_item_move(uiItem *item, int delta_xmin, int delta_xmax)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Button Groups
+ * \{ */
+
+/**
+ * Every function that adds a set of buttons must create another group,
+ * then #ui_def_but adds buttons to the current group (the last).
+ */
+static void layout_root_new_button_group(uiLayoutRoot *root)
+{
+ uiButtonGroup *new_group = MEM_mallocN(sizeof(uiButtonGroup), __func__);
+ BLI_listbase_clear(&new_group->buttons);
+ BLI_addtail(&root->button_groups, new_group);
+}
+
+static void button_group_add_but(uiLayoutRoot *root, uiBut *but)
+{
+ BLI_assert(root != NULL);
+
+ uiButtonGroup *current_button_group = root->button_groups.last;
+ BLI_assert(current_button_group != NULL);
+
+ /* We can't use the button directly because adding it to
+ * this list would mess with its prev and next pointers. */
+ LinkData *button_link = MEM_mallocN(sizeof(LinkData), __func__);
+ button_link->data = but;
+ BLI_addtail(&current_button_group->buttons, button_link);
+}
+
+static void button_group_free(uiButtonGroup *button_group)
+{
+ BLI_freelistN(&button_group->buttons);
+ MEM_freeN(button_group);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Special RNA Items
* \{ */
@@ -504,8 +552,7 @@ static void ui_item_array(uiLayout *layout,
int toggle,
bool icon_only,
bool compact,
- bool show_text,
- uiBut *label_but)
+ bool show_text)
{
const uiStyle *style = layout->root->style;
uiBut *but;
@@ -670,10 +717,7 @@ static void ui_item_array(uiLayout *layout,
/* special case, boolean array in a menu, this could be used in a more generic way too */
if (ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) && !expand && ELEM(len, 3, 4)) {
- but = uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, 0, 0, w, UI_UNIT_Y);
- if (label_but != NULL) {
- but->label_but = label_but;
- }
+ uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, 0, 0, w, UI_UNIT_Y);
}
else {
bool *boolarr = NULL;
@@ -724,13 +768,6 @@ static void ui_item_array(uiLayout *layout,
if ((a == 0) && (subtype == PROP_AXISANGLE)) {
UI_but_unit_type_set(but, PROP_UNIT_ROTATION);
}
-
- /* Set the label button for the array item. */
- if (label_but != NULL) {
- but->label_but = label_but;
- label_but = label_but->next;
- BLI_assert(label_but != NULL);
- }
}
if (boolarr) {
@@ -773,8 +810,7 @@ static void ui_item_enum_expand_elem_exec(uiLayout *layout,
const eButType but_type,
const bool icon_only,
const EnumPropertyItem *item,
- const bool is_first,
- uiBut *label_but)
+ const bool is_first)
{
const char *name = (!uiname || uiname[0]) ? item->name : "";
const int icon = item->icon;
@@ -813,10 +849,6 @@ static void ui_item_enum_expand_elem_exec(uiLayout *layout,
if (but_type == UI_BTYPE_TAB) {
but->flag |= UI_BUT_DRAG_LOCK;
}
-
- if (label_but != NULL) {
- but->label_but = label_but;
- }
}
static void ui_item_enum_expand_exec(uiLayout *layout,
@@ -826,8 +858,7 @@ static void ui_item_enum_expand_exec(uiLayout *layout,
const char *uiname,
const int h,
const eButType but_type,
- const bool icon_only,
- uiBut *label_but)
+ const bool icon_only)
{
/* XXX: The way this function currently handles uiname parameter
* is insane and inconsistent with general UI API:
@@ -903,7 +934,7 @@ static void ui_item_enum_expand_exec(uiLayout *layout,
}
ui_item_enum_expand_elem_exec(
- layout, block, ptr, prop, uiname, h, but_type, icon_only, item, is_first, label_but);
+ layout, block, ptr, prop, uiname, h, but_type, icon_only, item, is_first);
}
UI_block_layout_set_current(block, layout);
@@ -918,11 +949,9 @@ static void ui_item_enum_expand(uiLayout *layout,
PropertyRNA *prop,
const char *uiname,
const int h,
- const bool icon_only,
- uiBut *label_but)
+ const bool icon_only)
{
- ui_item_enum_expand_exec(
- layout, block, ptr, prop, uiname, h, UI_BTYPE_ROW, icon_only, label_but);
+ ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_ROW, icon_only);
}
static void ui_item_enum_expand_tabs(uiLayout *layout,
bContext *C,
@@ -937,7 +966,7 @@ static void ui_item_enum_expand_tabs(uiLayout *layout,
{
uiBut *last = block->buttons.last;
- ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_TAB, icon_only, NULL);
+ ui_item_enum_expand_exec(layout, block, ptr, prop, uiname, h, UI_BTYPE_TAB, icon_only);
BLI_assert(last != block->buttons.last);
const bool use_custom_highlight = (prop_highlight != NULL);
@@ -994,12 +1023,10 @@ static uiBut *ui_item_with_label(uiLayout *layout,
{
uiLayout *sub = layout;
uiBut *but = NULL;
- uiBut *label_but = NULL;
PropertyType type;
PropertySubType subtype;
int prop_but_width = w_hint;
#ifdef UI_PROP_DECORATE
- uiBut *decorator_but = NULL;
uiLayout *layout_prop_decorate = NULL;
const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
const bool use_prop_decorate = use_prop_sep && (layout->item.flag & UI_ITEM_PROP_DECORATE) &&
@@ -1020,7 +1047,7 @@ static uiBut *ui_item_with_label(uiLayout *layout,
#ifdef UI_PROP_DECORATE
if (name[0]) {
if (use_prop_sep) {
- label_but = uiItemL_respect_property_split(layout, name, 0, &layout_prop_decorate);
+ layout_prop_decorate = uiItemL_respect_property_split(layout, name, 0);
}
else
#endif
@@ -1036,8 +1063,7 @@ static uiBut *ui_item_with_label(uiLayout *layout,
else {
w_label = w_hint / 3;
}
- label_but = uiDefBut(
- block, UI_BTYPE_LABEL, 0, name, x, y, w_label, h, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, UI_BTYPE_LABEL, 0, name, x, y, w_label, h, NULL, 0.0, 0.0, 0, 0, "");
}
}
@@ -1115,15 +1141,10 @@ static uiBut *ui_item_with_label(uiLayout *layout,
#ifdef UI_PROP_DECORATE
/* Only for alignment. */
if (use_prop_decorate) { /* Note that sep flag may have been unset meanwhile. */
- decorator_but = uiItemL_(layout_prop_decorate ? layout_prop_decorate : sub, NULL, ICON_BLANK1);
+ uiItemL(layout_prop_decorate ? layout_prop_decorate : sub, NULL, ICON_BLANK1);
}
#endif /* UI_PROP_DECORATE */
- /* Set the button's label and decorator even if they are NULL. They can be changed
- * further with the return value of this function anyway. */
- but->label_but = label_but;
- but->decorator_but = decorator_but;
-
UI_block_layout_set_current(block, layout);
return but;
}
@@ -1962,34 +1983,28 @@ static uiLayout *ui_layout_heading_find(uiLayout *cur_layout)
return NULL;
}
-/**
- * \return The label button added.
- */
-static uiBut *ui_layout_heading_label_add(uiLayout *layout,
- uiLayout *heading_layout,
- bool right_align,
- bool respect_prop_split)
+static void ui_layout_heading_label_add(uiLayout *layout,
+ uiLayout *heading_layout,
+ bool right_align,
+ bool respect_prop_split)
{
const int prev_alignment = layout->alignment;
- uiBut *label_but = NULL;
if (right_align) {
uiLayoutSetAlignment(layout, UI_LAYOUT_ALIGN_RIGHT);
}
if (respect_prop_split) {
- label_but = uiItemL_respect_property_split(layout, heading_layout->heading, ICON_NONE, NULL);
+ uiItemL_respect_property_split(layout, heading_layout->heading, ICON_NONE);
}
else {
- label_but = uiItemL_(layout, heading_layout->heading, ICON_NONE);
+ uiItemL(layout, heading_layout->heading, ICON_NONE);
}
/* After adding the heading label, we have to mark it somehow as added, so it's not added again
* for other items in this layout. For now just clear it. */
heading_layout->heading[0] = '\0';
layout->alignment = prev_alignment;
-
- return label_but;
}
/**
@@ -2050,6 +2065,7 @@ void uiItemFullR(uiLayout *layout,
#endif /* UI_PROP_DECORATE */
UI_block_layout_set_current(block, layout);
+ layout_root_new_button_group(layout->root);
/* retrieve info */
const PropertyType type = RNA_property_type(prop);
@@ -2171,10 +2187,6 @@ void uiItemFullR(uiLayout *layout,
}
uiBut *but = NULL;
- /* Store the label to assign it to the button afterwards. This is the first
- * label button if the item is an array and there are a series of buttons.
- * Decorators are assigned as they are built later on. */
- uiBut *label_but = NULL;
/* Split the label / property. */
uiLayout *layout_parent = layout;
@@ -2194,7 +2206,7 @@ void uiItemFullR(uiLayout *layout,
layout = uiLayoutColumn(layout_row ? layout_row : layout, true);
layout->space = 0;
if (heading_layout) {
- label_but = ui_layout_heading_label_add(layout, heading_layout, false, false);
+ ui_layout_heading_label_add(layout, heading_layout, false, false);
}
}
else {
@@ -2221,43 +2233,39 @@ void uiItemFullR(uiLayout *layout,
*s++ = str[0];
*s++ = '\0';
}
- uiBut *new_label = uiDefBut(block,
- UI_BTYPE_LABEL,
- 0,
- use_prefix ? name_with_suffix : str,
- 0,
- 0,
- w,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- "");
- new_label->drawflag |= UI_BUT_TEXT_RIGHT;
- new_label->drawflag &= ~UI_BUT_TEXT_LEFT;
-
- if (a == 0) {
- label_but = new_label;
- }
+ but = uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 0,
+ use_prefix ? name_with_suffix : str,
+ 0,
+ 0,
+ w,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ but->drawflag |= UI_BUT_TEXT_RIGHT;
+ but->drawflag &= ~UI_BUT_TEXT_LEFT;
+
label_added = true;
}
}
else {
if (name) {
- label_but = uiDefBut(
+ but = uiDefBut(
block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- label_but->drawflag |= UI_BUT_TEXT_RIGHT;
- label_but->drawflag &= ~UI_BUT_TEXT_LEFT;
+ but->drawflag |= UI_BUT_TEXT_RIGHT;
+ but->drawflag &= ~UI_BUT_TEXT_LEFT;
label_added = true;
}
}
if (!label_added && heading_layout) {
- label_but = ui_layout_heading_label_add(layout_sub, heading_layout, true, false);
- label_added = true;
+ ui_layout_heading_label_add(layout_sub, heading_layout, true, false);
}
layout_split = ui_item_prop_split_layout_hack(layout_parent, layout_split);
@@ -2300,7 +2308,7 @@ void uiItemFullR(uiLayout *layout,
else if (heading_layout) {
/* Could not add heading to split layout, fallback to inserting it to the layout with the
* heading itself. */
- label_but = ui_layout_heading_label_add(heading_layout, heading_layout, false, false);
+ ui_layout_heading_label_add(heading_layout, heading_layout, false, false);
}
/* array property */
@@ -2327,29 +2335,26 @@ void uiItemFullR(uiLayout *layout,
toggle,
icon_only,
compact,
- !use_prop_sep_split_label,
- label_but);
+ !use_prop_sep_split_label);
}
/* enum item */
else if (type == PROP_ENUM && index == RNA_ENUM_VALUE) {
if (icon && name[0] && !icon_only) {
- but = uiDefIconTextButR_prop(
+ uiDefIconTextButR_prop(
block, UI_BTYPE_ROW, 0, icon, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
}
else if (icon) {
- but = uiDefIconButR_prop(
+ uiDefIconButR_prop(
block, UI_BTYPE_ROW, 0, icon, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
}
else {
- but = uiDefButR_prop(
+ uiDefButR_prop(
block, UI_BTYPE_ROW, 0, name, 0, 0, w, h, ptr, prop, -1, 0, value, -1, -1, NULL);
}
- BLI_assert(but != NULL);
- but->label_but = label_but;
}
/* expanded enum */
else if (type == PROP_ENUM && expand) {
- ui_item_enum_expand(layout, block, ptr, prop, name, h, icon_only, label_but);
+ ui_item_enum_expand(layout, block, ptr, prop, name, h, icon_only);
}
/* property with separate label */
else if (type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) {
@@ -2363,8 +2368,6 @@ void uiItemFullR(uiLayout *layout,
if (layout->activate_init) {
UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT);
}
- BLI_assert(but != NULL);
- but->label_but = label_but;
}
/* single button */
else {
@@ -2398,8 +2401,6 @@ void uiItemFullR(uiLayout *layout,
if (layout->activate_init) {
UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT);
}
-
- but->label_but = label_but;
}
/* The resulting button may have the icon set since boolean button drawing
@@ -2435,16 +2436,13 @@ void uiItemFullR(uiLayout *layout,
/* The icons are set in 'ui_but_anim_flag' */
uiItemDecoratorR_prop(layout_col, ptr_dec, prop_dec, but_decorate->rnaindex);
- uiBut *decorator = block->buttons.last;
- but_decorate->decorator_but = decorator;
+ but = block->buttons.last;
/* Order the decorator after the button we decorate, this is used so we can always
* do a quick lookup. */
- BLI_remlink(&block->buttons, decorator);
- BLI_insertlinkafter(&block->buttons, but_decorate, decorator);
-
- /* Assign decorator to the property's button so that they can be filtered together. */
- but_decorate = decorator->next;
+ BLI_remlink(&block->buttons, but);
+ BLI_insertlinkafter(&block->buttons, but_decorate, but);
+ but_decorate = but->next;
}
BLI_assert(ELEM(i, 1, ui_decorate.len));
@@ -2818,6 +2816,8 @@ void uiItemPointerR_prop(uiLayout *layout,
char namestr[UI_MAX_NAME_STR];
const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
+ layout_root_new_button_group(layout->root);
+
type = RNA_property_type(prop);
if (!ELEM(type, PROP_POINTER, PROP_STRING, PROP_ENUM)) {
RNA_warning("Property %s.%s must be a pointer, string or enum",
@@ -2923,6 +2923,7 @@ static uiBut *ui_item_menu(uiLayout *layout,
int w, h;
UI_block_layout_set_current(block, layout);
+ layout_root_new_button_group(layout->root);
if (!name) {
name = "";
@@ -3190,6 +3191,7 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon)
int w;
UI_block_layout_set_current(block, layout);
+ layout_root_new_button_group(layout->root);
if (!name) {
name = "";
@@ -3273,42 +3275,29 @@ uiPropertySplitWrapper uiItemPropertySplitWrapperCreate(uiLayout *parent_layout)
return split_wrapper;
}
-/**
+/*
* Helper to add a label and creates a property split layout if needed.
- *
- * \param r_layout: Returns a column to put decorators in if property separate is on, otherwise
- * returns the original layout.
*/
-uiBut *uiItemL_respect_property_split(uiLayout *layout,
- const char *text,
- int icon,
- uiLayout **r_layout)
+uiLayout *uiItemL_respect_property_split(uiLayout *layout, const char *text, int icon)
{
- uiBut *label_but;
if (layout->item.flag & UI_ITEM_PROP_SEP) {
uiBlock *block = uiLayoutGetBlock(layout);
const uiPropertySplitWrapper split_wrapper = uiItemPropertySplitWrapperCreate(layout);
/* Further items added to 'layout' will automatically be added to split_wrapper.property_row */
- label_but = uiItemL_(split_wrapper.label_column, text, icon);
+ uiItemL_(split_wrapper.label_column, text, icon);
UI_block_layout_set_current(block, split_wrapper.property_row);
- if (r_layout != NULL) {
- *r_layout = split_wrapper.decorate_column;
- }
+ return split_wrapper.decorate_column;
}
- else {
- char namestr[UI_MAX_NAME_STR];
- if (text) {
- text = ui_item_name_add_colon(text, namestr);
- }
- label_but = uiItemL_(layout, text, icon);
- if (r_layout != NULL) {
- *r_layout = layout;
- }
+ char namestr[UI_MAX_NAME_STR];
+ if (text) {
+ text = ui_item_name_add_colon(text, namestr);
}
- return label_but;
+ uiItemL_(layout, text, icon);
+
+ return layout;
}
void uiItemLDrag(uiLayout *layout, PointerRNA *ptr, const char *name, int icon)
@@ -5246,38 +5235,43 @@ static bool button_matches_search_filter(uiBut *but, const char *search_filter)
}
/**
- * Apply the search filter, tagging all buttons with whether they match or not.
+ * Test for a search result within the a specific button group.
*/
-static bool block_search_filter_tag_buttons(uiBlock *block)
+static bool button_group_has_search_match(uiButtonGroup *button_group, const char *search_filter)
{
- bool has_result = false;
- LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
- /* First match regular buttons. */
- if (!ELEM(but->type, UI_BTYPE_LABEL) &&
- button_matches_search_filter(but, block->search_filter)) {
- has_result = true;
- but->flag |= UI_SEARCH_FILTER_MATCHES;
- }
- /* Then match their labels. */
- if (but->label_but != NULL &&
- button_matches_search_filter(but->label_but, block->search_filter)) {
- has_result = true;
- but->flag |= UI_SEARCH_FILTER_MATCHES;
+ LISTBASE_FOREACH (LinkData *, link, &button_group->buttons) {
+ uiBut *but = link->data;
+ if (button_matches_search_filter(but, search_filter)) {
+ return true;
}
}
- /* Remove filter from labels and decorators that correspond to un-filtered buttons. */
- LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
- if (but->flag & UI_SEARCH_FILTER_MATCHES) {
- if (but->label_but != NULL) {
- but->label_but->flag |= UI_SEARCH_FILTER_MATCHES;
- }
- if (but->decorator_but != NULL) {
- but->decorator_but->flag |= UI_SEARCH_FILTER_MATCHES;
+ return false;
+}
+
+/**
+ * Apply the search filter, tagging all buttons with whether they match or not.
+ * Tag every button in the group as a search match if any button matches.
+ *
+ * \note It would be great to return early here if we found a match, but because
+ * the results could be visible we have to continue searching the entire block.
+ *
+ * \return Whether the block has any search results.
+ */
+static bool block_search_filter_tag_buttons(uiBlock *block)
+{
+ bool has_result = false;
+ LISTBASE_FOREACH (uiLayoutRoot *, root, &block->layouts) {
+ LISTBASE_FOREACH (uiButtonGroup *, button_group, &root->button_groups) {
+ if (button_group_has_search_match(button_group, block->search_filter)) {
+ LISTBASE_FOREACH (LinkData *, link, &button_group->buttons) {
+ uiBut *but = link->data;
+ but->flag |= UI_SEARCH_FILTER_MATCHES;
+ }
+ has_result = true;
}
}
}
-
return has_result;
}
@@ -5560,6 +5554,16 @@ static void ui_layout_free(uiLayout *layout)
MEM_freeN(layout);
}
+static void layout_root_free(uiLayoutRoot *root)
+{
+ ui_layout_free(root->layout);
+
+ LISTBASE_FOREACH_MUTABLE (uiButtonGroup *, button_group, &root->button_groups) {
+ button_group_free(button_group);
+ }
+ MEM_freeN(root);
+}
+
static void ui_layout_add_padding_button(uiLayoutRoot *root)
{
if (root->padding) {
@@ -5594,6 +5598,9 @@ uiLayout *UI_block_layout(uiBlock *block,
root->padding = padding;
root->opcontext = WM_OP_INVOKE_REGION_WIN;
+ BLI_listbase_clear(&root->button_groups);
+ layout_root_new_button_group(root);
+
layout = MEM_callocN(sizeof(uiLayout), "uiLayout");
layout->item.type = (type == UI_LAYOUT_VERT_BAR) ? ITEM_LAYOUT_COLUMN : ITEM_LAYOUT_ROOT;
@@ -5678,6 +5685,8 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
if (layout->emboss != UI_EMBOSS_UNDEFINED) {
but->emboss = layout->emboss;
}
+
+ button_group_add_but(layout->root, but);
}
bool ui_layout_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but)
@@ -5743,7 +5752,7 @@ void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y)
block->curlayout = NULL;
- LISTBASE_FOREACH (uiLayoutRoot *, root, &block->layouts) {
+ LISTBASE_FOREACH_MUTABLE (uiLayoutRoot *, root, &block->layouts) {
/* Seach only roots should be removed by #UI_block_apply_search_filter. */
BLI_assert(!root->search_only);
@@ -5751,10 +5760,10 @@ void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y)
/* NULL in advance so we don't interfere when adding button */
ui_layout_end(block, root->layout, r_x, r_y);
- ui_layout_free(root->layout);
+ layout_root_free(root);
}
- BLI_freelistN(&block->layouts);
+ BLI_listbase_clear(&block->layouts);
/* XXX silly trick, interface_templates.c doesn't get linked
* because it's not used by other files in this module? */
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 9141a46499e..77a9d9f549a 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -897,7 +897,7 @@ static void template_ID(const bContext *C,
if (text) {
/* Add label resepecting the separated layout property split state. */
- uiItemL_respect_property_split(layout, text, ICON_NONE, NULL);
+ uiItemL_respect_property_split(layout, text, ICON_NONE);
}
if (flag & UI_ID_BROWSE) {
diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt
index 66c055d9426..dd04732a814 100644
--- a/source/blender/editors/mask/CMakeLists.txt
+++ b/source/blender/editors/mask/CMakeLists.txt
@@ -30,10 +30,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
mask_add.c
mask_draw.c
@@ -51,6 +47,5 @@ set(SRC
set(LIB
)
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_mask "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt
index 589b51ce942..035af772a55 100644
--- a/source/blender/editors/mesh/CMakeLists.txt
+++ b/source/blender/editors/mesh/CMakeLists.txt
@@ -35,10 +35,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
editface.c
editmesh_add.c
@@ -97,6 +93,5 @@ if(WITH_GMP)
add_definitions(-DWITH_GMP)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_mesh "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 3c426e5d2b1..b7bf6230f22 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -104,7 +104,7 @@ static void make_prim_finish(bContext *C,
/* userdef */
if (exit_editmode) {
- ED_object_editmode_exit(C, EM_FREEDATA);
+ ED_object_editmode_exit_ex(CTX_data_main(C), CTX_data_scene(C), obedit, EM_FREEDATA);
}
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
}
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index 953ef8114f9..be6c0658b1f 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -39,10 +39,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
object_add.c
object_bake.c
@@ -81,7 +77,6 @@ set(LIB
bf_windowmanager
)
-add_definitions(${GL_DEFINITIONS})
if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 4de48fba494..fa1d147dc5e 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -529,9 +529,12 @@ Object *ED_object_add_type_with_obdata(bContext *C,
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob;
- /* for as long scene has editmode... */
- if (CTX_data_edit_object(C)) {
- ED_object_editmode_exit(C, EM_FREEDATA);
+ /* For as long scene has editmode... */
+ {
+ Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
+ if (obedit != NULL) {
+ ED_object_editmode_exit_ex(bmain, scene, obedit, EM_FREEDATA);
+ }
}
/* deselects all, sets active object */
@@ -778,18 +781,20 @@ static int effector_add_exec(bContext *C, wmOperator *op)
dia = RNA_float_get(op->ptr, "radius");
if (type == PFIELD_GUIDE) {
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
Curve *cu;
ob = ED_object_add_type(
C, OB_CURVE, get_effector_defname(type), loc, rot, false, local_view_bits);
cu = ob->data;
cu->flag |= CU_PATH | CU_3D;
- ED_object_editmode_enter(C, 0);
+ ED_object_editmode_enter_ex(bmain, scene, ob, 0);
ED_object_new_primitive_matrix(C, ob, loc, rot, mat);
BLI_addtail(&cu->editnurb->nurbs,
ED_curve_add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, dia));
if (!enter_editmode) {
- ED_object_editmode_exit(C, EM_FREEDATA);
+ ED_object_editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
}
}
else {
@@ -900,7 +905,10 @@ void OBJECT_OT_camera_add(wmOperatorType *ot)
static int object_metaball_add_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
bool newob = false;
bool enter_editmode;
ushort local_view_bits;
@@ -931,7 +939,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op)
/* userdef */
if (newob && !enter_editmode) {
- ED_object_editmode_exit(C, EM_FREEDATA);
+ ED_object_editmode_exit_ex(bmain, scene, obedit, EM_FREEDATA);
}
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
@@ -1017,7 +1025,11 @@ void OBJECT_OT_text_add(wmOperatorType *ot)
static int object_armature_add_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
+
RegionView3D *rv3d = CTX_wm_region_view3d(C);
bool newob = false;
bool enter_editmode;
@@ -1032,7 +1044,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
}
if ((obedit == NULL) || (obedit->type != OB_ARMATURE)) {
obedit = ED_object_add_type(C, OB_ARMATURE, NULL, loc, rot, true, local_view_bits);
- ED_object_editmode_enter(C, 0);
+ ED_object_editmode_enter_ex(bmain, scene, obedit, 0);
newob = true;
}
else {
@@ -1049,7 +1061,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
/* userdef */
if (newob && !enter_editmode) {
- ED_object_editmode_exit(C, EM_FREEDATA);
+ ED_object_editmode_exit_ex(bmain, scene, obedit, EM_FREEDATA);
}
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 8b10a865a68..85522209e29 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -80,8 +80,10 @@
/** \name Constraint Data Accessors
* \{ */
-/* If object is in posemode, return active bone constraints, else object constraints. No
- * constraints are returned for a bone on an inactive bonelayer. */
+/**
+ * If object is in pose-mode, return active bone constraints, else object constraints.
+ * No constraints are returned for a bone on an inactive bone-layer.
+ */
ListBase *ED_object_constraint_active_list(Object *ob)
{
if (ob == NULL) {
@@ -103,8 +105,10 @@ ListBase *ED_object_constraint_active_list(Object *ob)
return NULL;
}
-/* Get the constraints for the active pose bone. Bone may be on an inactive bonelayer (unlike
- * ED_object_constraint_active_list, such constraints are not excluded here). */
+/**
+ * Get the constraints for the active pose bone. Bone may be on an inactive bone-layer
+ * (unlike #ED_object_constraint_active_list, such constraints are not excluded here).
+ */
ListBase *ED_object_pose_constraint_list(const bContext *C)
{
bPoseChannel *pose_bone = CTX_data_pointer_get(C, "active_pose_bone").data;
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 966aeed75ab..7e0df736228 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -769,14 +769,14 @@ bool ED_object_editmode_enter(bContext *C, int flag)
static int editmode_toggle_exec(bContext *C, wmOperator *op)
{
- struct wmMsgBus *mbus = CTX_wm_message_bus(C);
- const int mode_flag = OB_MODE_EDIT;
- const bool is_mode_set = (CTX_data_edit_object(C) != NULL);
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
View3D *v3d = CTX_wm_view3d(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
Object *obact = OBACT(view_layer);
+ const int mode_flag = OB_MODE_EDIT;
+ const bool is_mode_set = (obact->mode & mode_flag) != 0;
+ struct wmMsgBus *mbus = CTX_wm_message_bus(C);
if (!is_mode_set) {
if (!ED_object_mode_compat_set(C, obact, mode_flag, op->reports)) {
@@ -785,7 +785,7 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op)
}
if (!is_mode_set) {
- ED_object_editmode_enter(C, 0);
+ ED_object_editmode_enter_ex(bmain, scene, obact, 0);
if (obact->mode & mode_flag) {
FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob) {
if ((ob != obact) && (ob->type == obact->type)) {
@@ -796,7 +796,8 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op)
}
}
else {
- ED_object_editmode_exit(C, EM_FREEDATA);
+ ED_object_editmode_exit_ex(bmain, scene, obact, EM_FREEDATA);
+
if ((obact->mode & mode_flag) == 0) {
FOREACH_OBJECT_BEGIN (view_layer, ob) {
if ((ob != obact) && (ob->type == obact->type)) {
@@ -859,6 +860,9 @@ void OBJECT_OT_editmode_toggle(wmOperatorType *ot)
static int posemode_exec(bContext *C, wmOperator *op)
{
struct wmMsgBus *mbus = CTX_wm_message_bus(C);
+ struct Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
Base *base = CTX_data_active_base(C);
/* If the base is NULL it means we have an active object, but the object itself is hidden. */
@@ -880,16 +884,17 @@ static int posemode_exec(bContext *C, wmOperator *op)
return OPERATOR_PASS_THROUGH;
}
- if (obact == CTX_data_edit_object(C)) {
- ED_object_editmode_exit(C, EM_FREEDATA);
- is_mode_set = false;
+ {
+ Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
+ if (obact == obedit) {
+ ED_object_editmode_exit_ex(bmain, scene, obedit, EM_FREEDATA);
+ is_mode_set = false;
+ }
}
if (is_mode_set) {
bool ok = ED_object_posemode_exit(C, obact);
if (ok) {
- struct Main *bmain = CTX_data_main(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
FOREACH_OBJECT_BEGIN (view_layer, ob) {
if ((ob != obact) && (ob->type == OB_ARMATURE) && (ob->mode & mode_flag)) {
ED_object_posemode_exit_ex(bmain, ob);
@@ -901,9 +906,7 @@ static int posemode_exec(bContext *C, wmOperator *op)
else {
bool ok = ED_object_posemode_enter(C, obact);
if (ok) {
- struct Main *bmain = CTX_data_main(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
+ const View3D *v3d = CTX_wm_view3d(C);
FOREACH_SELECTED_OBJECT_BEGIN (view_layer, v3d, ob) {
if ((ob != obact) && (ob->type == OB_ARMATURE) && (ob->mode == OB_MODE_OBJECT) &&
(!ID_IS_LINKED(ob))) {
diff --git a/source/blender/editors/physics/CMakeLists.txt b/source/blender/editors/physics/CMakeLists.txt
index 0998280c381..2b9d9aaa0e1 100644
--- a/source/blender/editors/physics/CMakeLists.txt
+++ b/source/blender/editors/physics/CMakeLists.txt
@@ -30,10 +30,6 @@ set(INC
../../../../intern/mantaflow/extern
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
dynamicpaint_ops.c
particle_boids.c
@@ -74,6 +70,5 @@ if(WITH_BULLET)
add_definitions(-DWITH_BULLET)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_physics "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/render/CMakeLists.txt b/source/blender/editors/render/CMakeLists.txt
index 7f7748bf52f..642e92592f1 100644
--- a/source/blender/editors/render/CMakeLists.txt
+++ b/source/blender/editors/render/CMakeLists.txt
@@ -34,10 +34,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
render_internal.c
render_opengl.c
@@ -61,7 +57,6 @@ else()
)
endif()
-add_definitions(${GL_DEFINITIONS})
if(WITH_FREESTYLE)
list(APPEND INC
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 25b4ddc15fd..509097c7a70 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -604,6 +604,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL) {
image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect, viewname);
}
+ ima->gpuflag |= IMA_GPU_REFRESH;
/* make jobs timer to send notifier */
*(rj->do_update) = true;
diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt
index dc355148ad3..1de5ad729c5 100644
--- a/source/blender/editors/screen/CMakeLists.txt
+++ b/source/blender/editors/screen/CMakeLists.txt
@@ -33,10 +33,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
area.c
area_query.c
@@ -64,6 +60,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_screen "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 51cfb912722..930f9890dd9 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -36,10 +36,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
paint_cursor.c
paint_curve.c
@@ -90,6 +86,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_sculpt_paint "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 3d8c718c8a9..55abb269660 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -142,7 +142,7 @@ typedef struct LoadTexData {
ViewContext *vc;
MTex *mtex;
- GLubyte *buffer;
+ uchar *buffer;
bool col;
struct ImagePool *pool;
@@ -160,7 +160,7 @@ static void load_tex_task_cb_ex(void *__restrict userdata,
ViewContext *vc = data->vc;
MTex *mtex = data->mtex;
- GLubyte *buffer = data->buffer;
+ uchar *buffer = data->buffer;
const bool col = data->col;
struct ImagePool *pool = data->pool;
@@ -230,7 +230,7 @@ static void load_tex_task_cb_ex(void *__restrict userdata,
/* Clamp to avoid precision overflow. */
CLAMP(avg, 0.0f, 1.0f);
- buffer[index] = 255 - (GLubyte)(255 * avg);
+ buffer[index] = 255 - (uchar)(255 * avg);
}
}
else {
@@ -254,7 +254,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
MTex *mtex = (primary) ? &br->mtex : &br->mask_mtex;
ePaintOverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags();
- GLubyte *buffer = NULL;
+ uchar *buffer = NULL;
int size;
bool refresh;
@@ -309,10 +309,10 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
target->old_col = col;
}
if (col) {
- buffer = MEM_mallocN(sizeof(GLubyte) * size * size * 4, "load_tex");
+ buffer = MEM_mallocN(sizeof(uchar) * size * size * 4, "load_tex");
}
else {
- buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
+ buffer = MEM_mallocN(sizeof(uchar) * size * size, "load_tex");
}
pool = BKE_image_pool_new();
@@ -381,7 +381,7 @@ static void load_tex_cursor_task_cb(void *__restrict userdata,
LoadTexData *data = userdata;
Brush *br = data->br;
- GLubyte *buffer = data->buffer;
+ uchar *buffer = data->buffer;
const int size = data->size;
@@ -398,7 +398,7 @@ static void load_tex_cursor_task_cb(void *__restrict userdata,
/* Falloff curve. */
float avg = BKE_brush_curve_strength_clamped(br, len, 1.0f);
- buffer[index] = (GLubyte)(255 * avg);
+ buffer[index] = (uchar)(255 * avg);
}
else {
buffer[index] = 0;
@@ -411,7 +411,7 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
bool init;
ePaintOverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags();
- GLubyte *buffer = NULL;
+ uchar *buffer = NULL;
int size;
const bool refresh = !cursor_snap.overlay_texture ||
@@ -452,7 +452,7 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
cursor_snap.size = size;
}
- buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
+ buffer = MEM_mallocN(sizeof(uchar) * size * size, "load_tex");
BKE_curvemapping_init(br->curve);
diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
index f07d22ed639..9b4b5b8d1e2 100644
--- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
@@ -36,6 +36,7 @@
#include "BKE_brush.h"
#include "BKE_context.h"
+#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
@@ -58,6 +59,7 @@
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_sculpt.h"
+#include "ED_undo.h"
#include "ED_view3d.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
@@ -285,11 +287,17 @@ void sculpt_dynamic_topology_disable_with_undo(Main *bmain,
Object *ob)
{
SculptSession *ss = ob->sculpt;
- if (ss->bm) {
- SCULPT_undo_push_begin("Dynamic topology disable");
- SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END);
+ if (ss->bm != NULL) {
+ /* May be false in background mode. */
+ const bool use_undo = G.background ? (ED_undo_stack_get() != NULL) : true;
+ if (use_undo) {
+ SCULPT_undo_push_begin("Dynamic topology disable");
+ SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END);
+ }
SCULPT_dynamic_topology_disable_ex(bmain, depsgraph, scene, ob, NULL);
- SCULPT_undo_push_end();
+ if (use_undo) {
+ SCULPT_undo_push_end();
+ }
}
}
@@ -300,10 +308,16 @@ static void sculpt_dynamic_topology_enable_with_undo(Main *bmain,
{
SculptSession *ss = ob->sculpt;
if (ss->bm == NULL) {
- SCULPT_undo_push_begin("Dynamic topology enable");
+ /* May be false in background mode. */
+ const bool use_undo = G.background ? (ED_undo_stack_get() != NULL) : true;
+ if (use_undo) {
+ SCULPT_undo_push_begin("Dynamic topology enable");
+ }
SCULPT_dynamic_topology_enable_ex(bmain, depsgraph, scene, ob);
- SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
- SCULPT_undo_push_end();
+ if (use_undo) {
+ SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
+ SCULPT_undo_push_end();
+ }
}
}
diff --git a/source/blender/editors/space_action/CMakeLists.txt b/source/blender/editors/space_action/CMakeLists.txt
index 6c43f8b9549..10dcc77fc24 100644
--- a/source/blender/editors/space_action/CMakeLists.txt
+++ b/source/blender/editors/space_action/CMakeLists.txt
@@ -28,10 +28,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
action_buttons.c
action_data.c
@@ -49,6 +45,5 @@ set(LIB
bf_blenlib
)
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_action "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_api/CMakeLists.txt b/source/blender/editors/space_api/CMakeLists.txt
index d948d84f1c3..573afb76f0e 100644
--- a/source/blender/editors/space_api/CMakeLists.txt
+++ b/source/blender/editors/space_api/CMakeLists.txt
@@ -20,6 +20,7 @@ set(INC
../io
../../blenkernel
../../blenlib
+ ../../gpu
../../makesdna
../../makesrna
../../windowmanager
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 29ad314cd65..2a18ffafc6c 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -33,6 +33,8 @@
#include "BKE_context.h"
#include "BKE_screen.h"
+#include "GPU_state.h"
+
#include "UI_interface.h"
#include "UI_view2d.h"
@@ -269,12 +271,18 @@ void ED_region_draw_cb_exit(ARegionType *art, void *handle)
void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type)
{
RegionDrawCB *rdc;
+ bool has_drawn_something = false;
for (rdc = region->type->drawcalls.first; rdc; rdc = rdc->next) {
if (rdc->type == type) {
rdc->draw(C, region, rdc->customdata);
+ has_drawn_something = true;
}
}
+ if (has_drawn_something) {
+ /* This is needed until we get rid of BGL which can change the states we are tracking. */
+ GPU_force_state();
+ }
}
/* ********************* space template *********************** */
diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt
index 75d91174470..ce0787dbdb9 100644
--- a/source/blender/editors/space_buttons/CMakeLists.txt
+++ b/source/blender/editors/space_buttons/CMakeLists.txt
@@ -28,10 +28,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
buttons_context.c
buttons_ops.c
@@ -48,7 +44,6 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt
index 2ea4bc97d18..8c7f59d61dd 100644
--- a/source/blender/editors/space_clip/CMakeLists.txt
+++ b/source/blender/editors/space_clip/CMakeLists.txt
@@ -33,10 +33,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
clip_buttons.c
clip_dopesheet_draw.c
@@ -68,7 +64,6 @@ set(LIB
bf_blenlib
)
-add_definitions(${GL_DEFINITIONS})
if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
diff --git a/source/blender/editors/space_console/CMakeLists.txt b/source/blender/editors/space_console/CMakeLists.txt
index 33934832ccc..e5aedd0d0de 100644
--- a/source/blender/editors/space_console/CMakeLists.txt
+++ b/source/blender/editors/space_console/CMakeLists.txt
@@ -28,10 +28,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
console_draw.c
console_ops.c
@@ -49,6 +45,5 @@ if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_console "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt
index 84df11ea39c..dcacf5e2504 100644
--- a/source/blender/editors/space_file/CMakeLists.txt
+++ b/source/blender/editors/space_file/CMakeLists.txt
@@ -33,10 +33,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
file_draw.c
file_ops.c
@@ -95,7 +91,6 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index 44131693628..b459c02d9e5 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -39,6 +39,7 @@ struct View2D;
void file_calc_previews(const bContext *C, ARegion *region);
void file_draw_list(const bContext *C, ARegion *region);
+void file_draw_check_ex(bContext *C, struct ScrArea *area);
void file_draw_check(bContext *C);
void file_draw_check_cb(bContext *C, void *arg1, void *arg2);
bool file_draw_check_exists(SpaceFile *sfile);
@@ -80,13 +81,13 @@ void file_filename_enter_handle(bContext *C, void *arg_unused, void *arg_but);
int file_highlight_set(struct SpaceFile *sfile, struct ARegion *region, int mx, int my);
void file_sfile_filepath_set(struct SpaceFile *sfile, const char *filepath);
-void file_sfile_to_operator_ex(bContext *C,
+void file_sfile_to_operator_ex(struct Main *bmain,
struct wmOperator *op,
struct SpaceFile *sfile,
char *filepath);
-void file_sfile_to_operator(bContext *C, struct wmOperator *op, struct SpaceFile *sfile);
+void file_sfile_to_operator(struct Main *bmain, struct wmOperator *op, struct SpaceFile *sfile);
-void file_operator_to_sfile(bContext *C, struct SpaceFile *sfile, struct wmOperator *op);
+void file_operator_to_sfile(struct Main *bmain, struct SpaceFile *sfile, struct wmOperator *op);
/* filesel.c */
void fileselect_file_set(SpaceFile *sfile, const int index);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 8c4b2a1b8a6..b3587fc7f97 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -1432,9 +1432,8 @@ void FILE_OT_cancel(struct wmOperatorType *ot)
/** \name Operator Utilities
* \{ */
-void file_sfile_to_operator_ex(bContext *C, wmOperator *op, SpaceFile *sfile, char *filepath)
+void file_sfile_to_operator_ex(Main *bmain, wmOperator *op, SpaceFile *sfile, char *filepath)
{
- Main *bmain = CTX_data_main(C);
PropertyRNA *prop;
/* XXX, not real length */
@@ -1507,16 +1506,15 @@ void file_sfile_to_operator_ex(bContext *C, wmOperator *op, SpaceFile *sfile, ch
}
}
}
-void file_sfile_to_operator(bContext *C, wmOperator *op, SpaceFile *sfile)
+void file_sfile_to_operator(Main *bmain, wmOperator *op, SpaceFile *sfile)
{
- char filepath[FILE_MAX];
+ char filepath_dummy[FILE_MAX];
- file_sfile_to_operator_ex(C, op, sfile, filepath);
+ file_sfile_to_operator_ex(bmain, op, sfile, filepath_dummy);
}
-void file_operator_to_sfile(bContext *C, SpaceFile *sfile, wmOperator *op)
+void file_operator_to_sfile(Main *bmain, SpaceFile *sfile, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
PropertyRNA *prop;
/* If neither of the above are set, split the filepath back */
@@ -1569,25 +1567,37 @@ void file_sfile_filepath_set(SpaceFile *sfile, const char *filepath)
}
}
-void file_draw_check(bContext *C)
+void file_draw_check_ex(bContext *C, ScrArea *area)
{
- SpaceFile *sfile = CTX_wm_space_file(C);
+ /* May happen when manipulating non-active spaces. */
+ if (UNLIKELY(area->spacetype != SPACE_FILE)) {
+ return;
+ }
+ SpaceFile *sfile = area->spacedata.first;
wmOperator *op = sfile->op;
if (op) { /* fail on reload */
if (op->type->check) {
- file_sfile_to_operator(C, op, sfile);
+ Main *bmain = CTX_data_main(C);
+ file_sfile_to_operator(bmain, op, sfile);
/* redraw */
if (op->type->check(C, op)) {
- file_operator_to_sfile(C, sfile, op);
+ file_operator_to_sfile(bmain, sfile, op);
/* redraw, else the changed settings wont get updated */
- ED_area_tag_redraw(CTX_wm_area(C));
+ ED_area_tag_redraw(area);
}
}
}
}
+void file_draw_check(bContext *C)
+{
+ SpaceFile *sfile = CTX_wm_space_file(C);
+ ScrArea *area = CTX_wm_area(C);
+ file_draw_check_ex(C, area);
+}
+
/* for use with; UI_block_func_set */
void file_draw_check_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
{
@@ -1675,7 +1685,7 @@ static int file_exec(bContext *C, wmOperator *exec_op)
sfile->op = NULL;
- file_sfile_to_operator_ex(C, op, sfile, filepath);
+ file_sfile_to_operator_ex(bmain, op, sfile, filepath);
if (BLI_exists(sfile->params->dir)) {
fsmenu_insert_entry(ED_fsmenu_get(),
@@ -2091,6 +2101,7 @@ void FILE_OT_smoothscroll(wmOperatorType *ot)
static int filepath_drop_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
SpaceFile *sfile = CTX_wm_space_file(C);
if (sfile) {
@@ -2105,7 +2116,7 @@ static int filepath_drop_exec(bContext *C, wmOperator *op)
file_sfile_filepath_set(sfile, filepath);
if (sfile->op) {
- file_sfile_to_operator(C, sfile->op, sfile);
+ file_sfile_to_operator(bmain, sfile->op, sfile);
file_draw_check(C);
}
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 306d6cba50e..9fc4e8936f4 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -828,13 +828,23 @@ FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *region)
return sfile->layout;
}
-void ED_file_change_dir(bContext *C)
+/**
+ * Support updating the directory even when this isn't the active space
+ * needed so RNA properties update function isn't context sensitive, see T70255.
+ */
+void ED_file_change_dir_ex(bContext *C, bScreen *screen, ScrArea *area)
{
- wmWindowManager *wm = CTX_wm_manager(C);
- SpaceFile *sfile = CTX_wm_space_file(C);
-
+ /* May happen when manipulating non-active spaces. */
+ if (UNLIKELY(area->spacetype != SPACE_FILE)) {
+ return;
+ }
+ SpaceFile *sfile = area->spacedata.first;
if (sfile->params) {
- ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+ wmWindowManager *wm = CTX_wm_manager(C);
+ Scene *scene = WM_windows_scene_get_from_screen(wm, screen);
+ if (LIKELY(scene != NULL)) {
+ ED_fileselect_clear(wm, scene, sfile);
+ }
/* Clear search string, it is very rare to want to keep that filter while changing dir,
* and usually very annoying to keep it actually! */
@@ -853,10 +863,17 @@ void ED_file_change_dir(bContext *C)
folderlist_pushdir(sfile->folders_prev, sfile->params->dir);
- file_draw_check(C);
+ file_draw_check_ex(C, area);
}
}
+void ED_file_change_dir(bContext *C)
+{
+ bScreen *screen = CTX_wm_screen(C);
+ ScrArea *area = CTX_wm_area(C);
+ ED_file_change_dir_ex(C, screen, area);
+}
+
int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file)
{
int match = 0;
diff --git a/source/blender/editors/space_graph/CMakeLists.txt b/source/blender/editors/space_graph/CMakeLists.txt
index 8170c920990..fd5c5863608 100644
--- a/source/blender/editors/space_graph/CMakeLists.txt
+++ b/source/blender/editors/space_graph/CMakeLists.txt
@@ -29,10 +29,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
graph_buttons.c
graph_draw.c
@@ -67,6 +63,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_graph "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index ba3ed620ff1..47f910402fe 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -423,7 +423,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
col = uiLayoutColumn(layout, true);
/* keyframe itself */
{
- uiItemL_respect_property_split(col, IFACE_("Key Frame"), ICON_NONE, NULL);
+ uiItemL_respect_property_split(col, IFACE_("Key Frame"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
@@ -441,7 +441,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
0,
NULL);
- uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE, NULL);
+ uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
@@ -468,7 +468,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
col = uiLayoutColumn(layout, true);
- uiItemL_respect_property_split(col, IFACE_("Left Handle Type"), ICON_NONE, NULL);
+ uiItemL_respect_property_split(col, IFACE_("Left Handle Type"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_MENU,
B_REDR,
@@ -487,7 +487,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
"Type of left handle");
UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
- uiItemL_respect_property_split(col, IFACE_("Frame"), ICON_NONE, NULL);
+ uiItemL_respect_property_split(col, IFACE_("Frame"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
@@ -506,7 +506,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
NULL);
UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
- uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE, NULL);
+ uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
@@ -532,7 +532,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
/* NOTE: special update callbacks are needed on the coords here due to T39911 */
col = uiLayoutColumn(layout, true);
- uiItemL_respect_property_split(col, IFACE_("Right Handle Type"), ICON_NONE, NULL);
+ uiItemL_respect_property_split(col, IFACE_("Right Handle Type"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_MENU,
B_REDR,
@@ -551,7 +551,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
"Type of right handle");
UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
- uiItemL_respect_property_split(col, IFACE_("Frame"), ICON_NONE, NULL);
+ uiItemL_respect_property_split(col, IFACE_("Frame"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
@@ -570,7 +570,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
NULL);
UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
- uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE, NULL);
+ uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE);
but = uiDefButR(block,
UI_BTYPE_NUM,
B_REDR,
diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt
index 24ec7a89397..96aab8b5d1a 100644
--- a/source/blender/editors/space_image/CMakeLists.txt
+++ b/source/blender/editors/space_image/CMakeLists.txt
@@ -35,10 +35,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
image_buttons.c
image_draw.c
@@ -81,6 +77,5 @@ if(WITH_IMAGE_CINEON)
add_definitions(-DWITH_CINEON)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_image "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 058436a46bf..60dd134646d 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -55,6 +55,7 @@
#include "BIF_glutil.h"
+#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
@@ -570,7 +571,8 @@ static void draw_image_buffer(const bContext *C,
float zoomy)
{
/* Image are still drawn in display space. */
- glDisable(GL_FRAMEBUFFER_SRGB);
+ GPUFrameBuffer *fb = GPU_framebuffer_active_get();
+ GPU_framebuffer_bind_no_srgb(fb);
int x, y;
int sima_flag = sima->flag & ED_space_image_get_display_channel_mask(ibuf);
@@ -660,7 +662,7 @@ static void draw_image_buffer(const bContext *C,
}
}
- glEnable(GL_FRAMEBUFFER_SRGB);
+ GPU_framebuffer_bind(fb);
}
static void draw_image_buffer_repeated(const bContext *C,
@@ -865,7 +867,7 @@ void draw_image_main(const bContext *C, ARegion *region)
Image *ima;
ImBuf *ibuf;
float zoomx, zoomy;
- bool show_viewer, show_render, show_paint, show_stereo3d, show_multilayer;
+ bool show_viewer, show_stereo3d, show_multilayer;
void *lock;
/* XXX can we do this in refresh? */
@@ -898,9 +900,6 @@ void draw_image_main(const bContext *C, ARegion *region)
}
show_viewer = (ima && ima->source == IMA_SRC_VIEWER) != 0;
- show_render = (show_viewer && ima->type == IMA_TYPE_R_RESULT) != 0;
- show_paint = (ima && (sima->mode == SI_MODE_PAINT) && (show_viewer == false) &&
- (show_render == false));
show_stereo3d = (ima && BKE_image_is_stereo(ima) && (sima->iuser.flag & IMA_SHOW_STEREO));
show_multilayer = ima && BKE_image_is_multilayer(ima);
@@ -998,16 +997,32 @@ void draw_image_main(const bContext *C, ARegion *region)
}
draw_udim_tile_grids(region, sima, ima);
-
- /* paint helpers */
- if (show_paint) {
- draw_image_paint_helpers(C, region, scene, zoomx, zoomy);
- }
+ draw_image_main_helpers(C, region);
if (show_viewer) {
BLI_thread_unlock(LOCK_DRAW_IMAGE);
}
+}
+
+void draw_image_main_helpers(const bContext *C, ARegion *region)
+{
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Scene *scene = CTX_data_scene(C);
+ Image *ima;
+ float zoomx, zoomy;
+ bool show_viewer, show_render, show_paint;
+ ima = ED_space_image(sima);
+ ED_space_image_get_zoom(sima, region, &zoomx, &zoomy);
+
+ show_viewer = (ima && ima->source == IMA_SRC_VIEWER) != 0;
+ show_render = (show_viewer && ima->type == IMA_TYPE_R_RESULT) != 0;
+ show_paint = (ima && (sima->mode == SI_MODE_PAINT) && (show_viewer == false) &&
+ (show_render == false));
+ /* paint helpers */
+ if (show_paint) {
+ draw_image_paint_helpers(C, region, scene, zoomx, zoomy);
+ }
/* render info */
if (ima && show_render) {
draw_render_info(C, sima->iuser.scene, ima, region, zoomx, zoomy);
diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h
index e6f5988aed8..100556ad29a 100644
--- a/source/blender/editors/space_image/image_intern.h
+++ b/source/blender/editors/space_image/image_intern.h
@@ -37,6 +37,7 @@ extern const char *image_context_dir[]; /* doc access */
/* image_draw.c */
void draw_image_main(const struct bContext *C, struct ARegion *region);
+void draw_image_main_helpers(const struct bContext *C, struct ARegion *region);
void draw_image_cache(const struct bContext *C, struct ARegion *region);
void draw_image_grease_pencil(struct bContext *C, bool onlyv2d);
void draw_image_sample_line(struct SpaceImage *sima);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index aa3f6446d51..f1becd5f027 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -76,6 +76,7 @@
#include "GPU_framebuffer.h"
#include "GPU_viewport.h"
+#include "DRW_engine.h"
#include "DRW_engine_types.h"
#include "image_intern.h"
@@ -638,8 +639,6 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
View2D *v2d = &region->v2d;
- // View2DScrollers *scrollers;
- float col[3];
GPUViewport *viewport = WM_draw_region_get_viewport(region);
GPUFrameBuffer *framebuffer_default, *framebuffer_overlay;
@@ -647,35 +646,14 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
framebuffer_default = GPU_viewport_framebuffer_default_get(viewport);
framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
- GPU_framebuffer_bind(framebuffer_default);
- GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
-
- GPU_framebuffer_bind(framebuffer_overlay);
-
/* XXX not supported yet, disabling for now */
scene->r.scemode &= ~R_COMP_CROP;
- /* clear and setup matrix */
- UI_GetThemeColor3fv(TH_BACK, col);
- srgb_to_linearrgb_v3_v3(col, col);
- GPU_clear_color(col[0], col[1], col[2], 1.0f);
- GPU_depth_test(GPU_DEPTH_NONE);
-
image_user_refresh_scene(C, sima);
/* we set view2d from own zoom and offset each time */
image_main_region_set_view2d(sima, region);
- /* we draw image in pixelspace */
- draw_image_main(C, region);
-
- /* and uvs in 0.0-1.0 space */
- UI_view2d_view_ortho(v2d);
-
- ED_region_draw_cb_draw(C, region, REGION_DRAW_PRE_VIEW);
-
- ED_uvedit_draw_main(sima, scene, view_layer, obedit, obact, depsgraph);
-
/* check for mask (delay draw) */
if (ED_space_image_show_uvedit(sima, obedit)) {
show_uvedit = true;
@@ -687,21 +665,52 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
show_curve = true;
}
- ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
+ /* we draw image in pixelspace */
+ if (!U.experimental.use_image_editor_legacy_drawing) {
+ DRW_draw_view(C);
+ draw_image_main_helpers(C, region);
- if (sima->flag & SI_SHOW_GPENCIL) {
- /* Grease Pencil too (in addition to UV's) */
- draw_image_grease_pencil((bContext *)C, true);
+ /* sample line */
+ UI_view2d_view_ortho(v2d);
+ draw_image_sample_line(sima);
+ UI_view2d_view_restore(C);
}
+ else {
+ GPU_framebuffer_bind(framebuffer_default);
+ GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f);
+
+ GPU_framebuffer_bind(framebuffer_overlay);
+
+ float col[3];
+ /* clear and setup matrix */
+ UI_GetThemeColor3fv(TH_BACK, col);
+ srgb_to_linearrgb_v3_v3(col, col);
+ GPU_clear_color(col[0], col[1], col[2], 1.0f);
+ GPU_depth_test(GPU_DEPTH_NONE);
+ draw_image_main(C, region);
+
+ /* and uvs in 0.0-1.0 space */
+ UI_view2d_view_ortho(v2d);
+
+ ED_region_draw_cb_draw(C, region, REGION_DRAW_PRE_VIEW);
- /* sample line */
- draw_image_sample_line(sima);
+ ED_uvedit_draw_main(sima, scene, view_layer, obedit, obact, depsgraph);
- UI_view2d_view_restore(C);
+ ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
- if (sima->flag & SI_SHOW_GPENCIL) {
- /* draw Grease Pencil - screen space only */
- draw_image_grease_pencil((bContext *)C, false);
+ if (sima->flag & SI_SHOW_GPENCIL) {
+ /* Grease Pencil too (in addition to UV's) */
+ draw_image_grease_pencil((bContext *)C, true);
+ }
+ /* sample line */
+ draw_image_sample_line(sima);
+
+ UI_view2d_view_restore(C);
+
+ if (sima->flag & SI_SHOW_GPENCIL) {
+ /* draw Grease Pencil - screen space only */
+ draw_image_grease_pencil((bContext *)C, false);
+ }
}
if (mask) {
@@ -741,7 +750,7 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
C);
}
- if (show_uvedit || mask || show_curve) {
+ if ((show_uvedit || mask || show_curve) && U.experimental.use_image_editor_legacy_drawing) {
UI_view2d_view_ortho(v2d);
ED_image_draw_cursor(region, sima->cursor);
UI_view2d_view_restore(C);
diff --git a/source/blender/editors/space_info/CMakeLists.txt b/source/blender/editors/space_info/CMakeLists.txt
index ad410e0aade..b6df07eec4e 100644
--- a/source/blender/editors/space_info/CMakeLists.txt
+++ b/source/blender/editors/space_info/CMakeLists.txt
@@ -33,10 +33,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
-
set(SRC
info_draw.c
info_ops.c
@@ -56,6 +52,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_info "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_nla/CMakeLists.txt b/source/blender/editors/space_nla/CMakeLists.txt
index 60152bffaf4..9a94d28c604 100644
--- a/source/blender/editors/space_nla/CMakeLists.txt
+++ b/source/blender/editors/space_nla/CMakeLists.txt
@@ -29,9 +29,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
nla_buttons.c
@@ -54,6 +51,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_nla "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt
index f8c30f9a688..fc831bf8490 100644
--- a/source/blender/editors/space_node/CMakeLists.txt
+++ b/source/blender/editors/space_node/CMakeLists.txt
@@ -34,9 +34,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
drawnode.c
@@ -75,6 +72,5 @@ if(WITH_OPENIMAGEDENOISE)
add_definitions(-DWITH_OPENIMAGEDENOISE)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_node "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt
index 616915dbc2c..db38839f959 100644
--- a/source/blender/editors/space_outliner/CMakeLists.txt
+++ b/source/blender/editors/space_outliner/CMakeLists.txt
@@ -30,9 +30,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
outliner_collections.c
@@ -60,6 +57,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_outliner "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_script/CMakeLists.txt b/source/blender/editors/space_script/CMakeLists.txt
index 0bd2a01a151..f2dd39ea13d 100644
--- a/source/blender/editors/space_script/CMakeLists.txt
+++ b/source/blender/editors/space_script/CMakeLists.txt
@@ -27,9 +27,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
script_edit.c
@@ -49,6 +46,5 @@ if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_script "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt
index 8105891e157..caf75349454 100644
--- a/source/blender/editors/space_sequencer/CMakeLists.txt
+++ b/source/blender/editors/space_sequencer/CMakeLists.txt
@@ -32,9 +32,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
sequencer_add.c
@@ -73,6 +70,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_sequencer "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_statusbar/CMakeLists.txt b/source/blender/editors/space_statusbar/CMakeLists.txt
index ad4c060a1f6..a0f3afecaf9 100644
--- a/source/blender/editors/space_statusbar/CMakeLists.txt
+++ b/source/blender/editors/space_statusbar/CMakeLists.txt
@@ -29,9 +29,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
space_statusbar.c
@@ -42,6 +39,5 @@ set(LIB
bf_blenlib
)
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_statusbar "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_text/CMakeLists.txt b/source/blender/editors/space_text/CMakeLists.txt
index 740fc9948ef..abd7620ea2b 100644
--- a/source/blender/editors/space_text/CMakeLists.txt
+++ b/source/blender/editors/space_text/CMakeLists.txt
@@ -29,9 +29,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
space_text.c
@@ -56,7 +53,6 @@ set(LIB
bf_blenlib
)
-add_definitions(${GL_DEFINITIONS})
if(WITH_PYTHON)
list(APPEND INC
diff --git a/source/blender/editors/space_topbar/CMakeLists.txt b/source/blender/editors/space_topbar/CMakeLists.txt
index d56e1da334d..15e71e2296d 100644
--- a/source/blender/editors/space_topbar/CMakeLists.txt
+++ b/source/blender/editors/space_topbar/CMakeLists.txt
@@ -29,9 +29,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
space_topbar.c
@@ -40,6 +37,5 @@ set(SRC
set(LIB
)
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_space_topbar "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index f2536cfac62..f4d6f7e322c 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -38,9 +38,6 @@ set(INC
${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
drawobject.c
@@ -85,7 +82,6 @@ if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
endif()
-add_definitions(${GL_DEFINITIONS})
if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index f3300f21628..0b5daece556 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1065,7 +1065,7 @@ static void draw_rotation_guide(const RegionView3D *rv3d)
float o[3]; /* center of rotation */
float end[3]; /* endpoints for drawing */
- GLubyte color[4] = {0, 108, 255, 255}; /* bright blue so it matches device LEDs */
+ uchar color[4] = {0, 108, 255, 255}; /* bright blue so it matches device LEDs */
negate_v3_v3(o, rv3d->ofs);
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index b284ba0af2d..f905e96dbdd 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -33,9 +33,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
transform.c
@@ -125,6 +122,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_transform "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 84eac3bbf8f..0eaae7f17cd 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -163,41 +163,6 @@ void constraintNumInput(TransInfo *t, float vec[3])
}
}
-static void postConstraintChecks(TransInfo *t, float vec[3])
-{
- mul_m3_v3(t->spacemtx_inv, vec);
-
- transform_snap_increment(t, vec);
-
- if (t->flag & T_NULL_ONE) {
- if (!(t->con.mode & CON_AXIS0)) {
- vec[0] = 1.0f;
- }
-
- if (!(t->con.mode & CON_AXIS1)) {
- vec[1] = 1.0f;
- }
-
- if (!(t->con.mode & CON_AXIS2)) {
- vec[2] = 1.0f;
- }
- }
-
- if (applyNumInput(&t->num, vec)) {
- constraintNumInput(t, vec);
- removeAspectRatio(t, vec);
- }
-
- /* If `t->values` is operator param, use that directly but not if snapping is forced */
- if (t->flag & T_INPUT_IS_VALUES_FINAL && (t->tsnap.status & SNAP_FORCED) == 0) {
- copy_v3_v3(vec, t->values);
- constraintValuesFinal(t, vec);
- /* inverse transformation at the end */
- }
-
- mul_m3_v3(t->spacemtx, vec);
-}
-
static void viewAxisCorrectCenter(const TransInfo *t, float t_con_center[3])
{
if (t->spacetype == SPACE_VIEW3D) {
@@ -432,15 +397,22 @@ static void applyAxisConstraintVec(
{
copy_v3_v3(out, in);
if (!td && t->con.mode & CON_APPLY) {
+ bool is_snap_to_point = false, is_snap_to_edge = false, is_snap_to_face = false;
mul_m3_v3(t->con.pmtx, out);
- bool is_snap_to_edge = false, is_snap_to_face = false;
+
if (activeSnap(t)) {
- is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0;
- is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE) != 0;
+ if (validSnap(t)) {
+ is_snap_to_point = (t->tsnap.snapElem & SCE_SNAP_MODE_VERTEX) != 0;
+ is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0;
+ is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE) != 0;
+ }
+ else if (t->tsnap.snapElem & SCE_SNAP_MODE_GRID) {
+ is_snap_to_point = true;
+ }
}
/* With snap points, a projection is alright, no adjustments needed. */
- if (!validSnap(t) || is_snap_to_edge || is_snap_to_face) {
+ if (!is_snap_to_point || is_snap_to_edge || is_snap_to_face) {
const int dims = getConstraintSpaceDimension(t);
if (dims == 2) {
if (!is_zero_v3(out)) {
@@ -486,7 +458,6 @@ static void applyAxisConstraintVec(
}
}
}
- postConstraintChecks(t, out);
}
}
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index 7ad54a56545..06ab60d992c 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -1296,6 +1296,9 @@ void mesh_customdatacorrect_init(TransInfo *t)
use_merge_group = (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT_KEEP_CONNECTED) != 0;
}
}
+ else {
+ return;
+ }
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
mesh_customdatacorrect_init_container(tc, use_merge_group);
diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
index 141f9acdeb4..d2474d78387 100644
--- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c
@@ -93,22 +93,29 @@ static void applySeqSlideValue(TransInfo *t, const float val[2])
static void applySeqSlide(TransInfo *t, const int mval[2])
{
char str[UI_MAX_DRAW_STR];
+ float values_final[3];
snapSequenceBounds(t, mval);
-
- if (t->con.mode & CON_APPLY) {
- float tvec[3];
- t->con.applyVec(t, NULL, NULL, t->values, tvec);
- copy_v3_v3(t->values_final, tvec);
+ if (applyNumInput(&t->num, values_final)) {
+ if (t->con.mode & CON_APPLY) {
+ if (t->con.mode & CON_AXIS0) {
+ /* Do nothing. */
+ }
+ else {
+ mul_v2_v2fl(values_final, t->spacemtx[1], values_final[0]);
+ }
+ }
+ }
+ else if (t->con.mode & CON_APPLY) {
+ t->con.applyVec(t, NULL, NULL, t->values, values_final);
}
else {
- // transform_snap_increment(t, t->values);
- applyNumInput(&t->num, t->values);
- copy_v3_v3(t->values_final, t->values);
+ copy_v2_v2(values_final, t->values);
}
- t->values_final[0] = floorf(t->values_final[0] + 0.5f);
- t->values_final[1] = floorf(t->values_final[1] + 0.5f);
+ values_final[0] = floorf(values_final[0] + 0.5f);
+ values_final[1] = floorf(values_final[1] + 0.5f);
+ copy_v2_v2(t->values_final, values_final);
headerSeqSlide(t, t->values_final, str);
applySeqSlideValue(t, t->values_final);
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c
index 866b9d921c8..758a6d04f11 100644
--- a/source/blender/editors/transform/transform_mode_translate.c
+++ b/source/blender/editors/transform/transform_mode_translate.c
@@ -360,42 +360,49 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2]))
if (t->flag & T_INPUT_IS_VALUES_FINAL) {
mul_v3_m3v3(global_dir, t->spacemtx, t->values);
}
+ else if (applyNumInput(&t->num, global_dir)) {
+ if (t->con.mode & CON_APPLY) {
+ if (t->con.mode & CON_AXIS0) {
+ /* Do nothing. */
+ }
+ else if (t->con.mode & CON_AXIS1) {
+ mul_v3_v3fl(global_dir, t->spacemtx[1], global_dir[0]);
+ }
+ else if (t->con.mode & CON_AXIS2) {
+ mul_v3_v3fl(global_dir, t->spacemtx[2], global_dir[0]);
+ }
+ }
+ }
else {
copy_v3_v3(global_dir, t->values);
- if (applyNumInput(&t->num, global_dir)) {
- removeAspectRatio(t, global_dir);
+
+ t->tsnap.snapElem = 0;
+ applySnapping(t, global_dir);
+ transform_snap_grid(t, global_dir);
+
+ if (t->con.mode & CON_APPLY) {
+ float in[3];
+ copy_v3_v3(in, global_dir);
+ t->con.applyVec(t, NULL, NULL, in, global_dir);
}
- else {
- applySnapping(t, global_dir);
- if (!validSnap(t) && !(t->con.mode & CON_APPLY)) {
- float dist_sq = FLT_MAX;
- if (transform_snap_grid(t, global_dir)) {
- dist_sq = len_squared_v3v3(t->values, global_dir);
- }
+ float incr_dir[3];
+ mul_v3_m3v3(incr_dir, t->spacemtx_inv, global_dir);
+ if (transform_snap_increment(t, incr_dir)) {
+ mul_v3_m3v3(incr_dir, t->spacemtx, incr_dir);
- /* Check the snap distance to the initial value to work with mixed snap. */
- float increment_loc[3];
- copy_v3_v3(increment_loc, t->values);
- if (transform_snap_increment(t, increment_loc)) {
- if ((dist_sq == FLT_MAX) || (len_squared_v3v3(t->values, increment_loc) < dist_sq)) {
- copy_v3_v3(global_dir, increment_loc);
- }
- }
+ /* Test for mixed snap with grid. */
+ float snap_dist_sq = FLT_MAX;
+ if (t->tsnap.snapElem != 0) {
+ snap_dist_sq = len_squared_v3v3(t->values, global_dir);
+ }
+ if ((snap_dist_sq == FLT_MAX) || (len_squared_v3v3(global_dir, incr_dir) < snap_dist_sq)) {
+ copy_v3_v3(global_dir, incr_dir);
}
}
}
- if (t->con.mode & CON_APPLY) {
- float in[3];
- copy_v3_v3(in, global_dir);
- t->con.applyVec(t, NULL, NULL, in, global_dir);
- headerTranslation(t, global_dir, str);
- }
- else {
- headerTranslation(t, global_dir, str);
- }
-
+ headerTranslation(t, global_dir, str);
applyTranslationValue(t, global_dir);
/* evil hack - redo translation if clipping needed */
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 1813acadb9e..a546aabd095 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -464,6 +464,7 @@ void applySnapping(TransInfo *t, float *vec)
void resetSnapping(TransInfo *t)
{
t->tsnap.status = 0;
+ t->tsnap.snapElem = 0;
t->tsnap.align = false;
t->tsnap.project = 0;
t->tsnap.mode = 0;
@@ -1412,12 +1413,12 @@ void snapSequenceBounds(TransInfo *t, const int mval[2])
t->values[0] = frame_near - frame_snap;
}
-static void snap_grid_apply_ex(
+static void snap_grid_apply(
TransInfo *t, const int max_index, const float grid_dist, const float loc[3], float r_out[3])
{
+ BLI_assert(max_index <= 2);
const float *center_global = t->center_global;
const float *asp = t->aspect;
- bool use_local_axis = false;
/* use a fallback for cursor selection,
* this isn't useful as a global center for absolute grid snapping
@@ -1427,74 +1428,27 @@ static void snap_grid_apply_ex(
center_global = cd->global;
}
- if (t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2)) {
- use_local_axis = true;
+ float in[3];
+ if (t->con.mode & CON_APPLY) {
+ BLI_assert(t->tsnap.snapElem == 0);
+ t->con.applyVec(t, NULL, NULL, loc, in);
+ }
+ else {
+ copy_v3_v3(in, loc);
}
for (int i = 0; i <= max_index; i++) {
- /* do not let unconstrained axis jump to absolute grid increments */
- if (!(t->con.mode & CON_APPLY) || t->con.mode & (CON_AXIS0 << i)) {
- const float iter_fac = grid_dist * asp[i];
-
- if (use_local_axis) {
- float local_axis[3];
- float pos_on_axis[3];
-
- copy_v3_v3(local_axis, t->spacemtx[i]);
- copy_v3_v3(pos_on_axis, t->spacemtx[i]);
-
- /* amount of movement on axis from initial pos */
- mul_v3_fl(pos_on_axis, loc[i]);
-
- /* actual global position on axis */
- add_v3_v3(pos_on_axis, center_global);
-
- float min_dist = INFINITY;
- for (int j = 0; j < 3; j++) {
- if (fabs(local_axis[j]) < 0.01f) {
- /* Ignore very small (normalized) axis changes */
- continue;
- }
-
- /* closest point on grid */
- float grid_p = iter_fac * roundf(pos_on_axis[j] / iter_fac);
- float dist_p = fabs((grid_p - pos_on_axis[j]) / local_axis[j]);
-
- /* The amount of distance needed to travel along the
- * local axis to snap to the closest grid point */
- /* in the global j axis direction */
- float move_dist = (grid_p - center_global[j]) / local_axis[j];
-
- if (dist_p < min_dist) {
- min_dist = dist_p;
- r_out[i] = move_dist;
- }
- }
- }
- else {
- r_out[i] = iter_fac * roundf((loc[i] + center_global[i]) / iter_fac) - center_global[i];
- }
- }
+ const float iter_fac = grid_dist * asp[i];
+ r_out[i] = iter_fac * roundf((in[i] + center_global[i]) / iter_fac) - center_global[i];
}
}
-static void snap_grid_apply(TransInfo *t, int max_index, const float grid_dist, float *r_val)
+bool transform_snap_grid(TransInfo *t, float *val)
{
- BLI_assert(t->tsnap.mode & SCE_SNAP_MODE_GRID);
- BLI_assert(max_index <= 2);
-
- /* Early bailing out if no need to snap */
- if (grid_dist == 0.0f) {
- return;
+ if (!activeSnap(t)) {
+ return false;
}
- /* absolute snapping on grid based on global center.
- * for now only 3d view (others can be added if we want) */
- snap_grid_apply_ex(t, max_index, grid_dist, r_val, r_val);
-}
-
-bool transform_snap_grid(TransInfo *t, float *val)
-{
if ((!(t->tsnap.mode & SCE_SNAP_MODE_GRID)) || validSnap(t)) {
/* Don't do grid snapping if there is a valid snap point. */
return false;
@@ -1508,10 +1462,15 @@ bool transform_snap_grid(TransInfo *t, float *val)
return false;
}
- float grid_dist = activeSnap(t) ? (t->modifiers & MOD_PRECISION) ? t->snap[2] : t->snap[1] :
- t->snap[0];
+ float grid_dist = (t->modifiers & MOD_PRECISION) ? t->snap[2] : t->snap[1];
+
+ /* Early bailing out if no need to snap */
+ if (grid_dist == 0.0f) {
+ return false;
+ }
- snap_grid_apply(t, t->idx_max, grid_dist, val);
+ snap_grid_apply(t, t->idx_max, grid_dist, val, val);
+ t->tsnap.snapElem = SCE_SNAP_MODE_GRID;
return true;
}
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 207606c2dcd..e05d1fedf6d 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -33,9 +33,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
ed_transverts.c
@@ -106,7 +103,6 @@ set(SRC
set(LIB
)
-add_definitions(${GL_DEFINITIONS})
if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
diff --git a/source/blender/editors/uvedit/CMakeLists.txt b/source/blender/editors/uvedit/CMakeLists.txt
index a39234561c2..f1751ef8d27 100644
--- a/source/blender/editors/uvedit/CMakeLists.txt
+++ b/source/blender/editors/uvedit/CMakeLists.txt
@@ -31,9 +31,6 @@ set(INC
../../../../intern/guardedalloc
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
uvedit_buttons.c
@@ -58,6 +55,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_uvedit "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt
index 497cb4a10a5..22f8f01be4b 100644
--- a/source/blender/gpencil_modifiers/CMakeLists.txt
+++ b/source/blender/gpencil_modifiers/CMakeLists.txt
@@ -76,6 +76,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_gpencil_modifiers "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 72dc610f3c8..b7ffa59538a 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -62,7 +62,6 @@ set(SRC
intern/gpu_capabilities.cc
intern/gpu_codegen.c
intern/gpu_context.cc
- intern/gpu_debug.cc
intern/gpu_drawlist.cc
intern/gpu_framebuffer.cc
intern/gpu_immediate.cc
@@ -113,10 +112,8 @@ set(SRC
GPU_capabilities.h
GPU_common.h
GPU_context.h
- GPU_debug.h
GPU_drawlist.h
GPU_framebuffer.h
- GPU_glew.h
GPU_immediate.h
GPU_immediate_util.h
GPU_index_buffer.h
diff --git a/source/blender/gpu/GPU_capabilities.h b/source/blender/gpu/GPU_capabilities.h
index b8a48735548..9d55fe73708 100644
--- a/source/blender/gpu/GPU_capabilities.h
+++ b/source/blender/gpu/GPU_capabilities.h
@@ -45,6 +45,8 @@ bool GPU_depth_blitting_workaround(void);
bool GPU_use_main_context_workaround(void);
bool GPU_crappy_amd_driver(void);
+bool GPU_shader_image_load_store_support(void);
+
bool GPU_mem_stats_supported(void);
void GPU_mem_stats_get(int *totalmem, int *freemem);
diff --git a/source/blender/gpu/GPU_common.h b/source/blender/gpu/GPU_common.h
index 8fd1baba2f7..1be74701176 100644
--- a/source/blender/gpu/GPU_common.h
+++ b/source/blender/gpu/GPU_common.h
@@ -32,10 +32,6 @@
# define TRUST_NO_ONE 1
#endif
-#if defined(WITH_OPENGL)
-# include <GL/glew.h>
-#endif
-
#include "BLI_sys_types.h"
#include <stdbool.h>
#include <stdint.h>
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index 5e872001267..a857736acd5 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -35,6 +35,14 @@ typedef enum eGPUWriteMask {
ENUM_OPERATORS(eGPUWriteMask)
+typedef enum eGPUBarrier {
+ GPU_BARRIER_NONE = 0,
+ GPU_BARRIER_SHADER_IMAGE_ACCESS = (1 << 0),
+ GPU_BARRIER_TEXTURE_FETCH = (1 << 1),
+} eGPUBarrier;
+
+ENUM_OPERATORS(eGPUBarrier)
+
/**
* Defines the fixed pipeline blending equation.
* SRC is the output color from the shader.
@@ -151,6 +159,10 @@ eGPUStencilTest GPU_stencil_test_get(void);
void GPU_flush(void);
void GPU_finish(void);
+void GPU_apply_state(void);
+void GPU_force_state(void);
+
+void GPU_memory_barrier(eGPUBarrier barrier);
#ifdef __cplusplus
}
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 2ce2ba093cf..99a7c6a5f0c 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -243,6 +243,10 @@ void GPU_texture_bind_ex(GPUTexture *tex, eGPUSamplerState state, int unit, cons
void GPU_texture_unbind(GPUTexture *tex);
void GPU_texture_unbind_all(void);
+void GPU_texture_image_bind(GPUTexture *tex, int unit);
+void GPU_texture_image_unbind(GPUTexture *tex);
+void GPU_texture_image_unbind_all(void);
+
void GPU_texture_copy(GPUTexture *dst, GPUTexture *src);
void GPU_texture_generate_mipmap(GPUTexture *tex);
@@ -253,7 +257,6 @@ void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter);
void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat, bool use_clamp);
void GPU_texture_swizzle_set(GPUTexture *tex, const char swizzle[4]);
-int GPU_texture_target(const GPUTexture *tex);
int GPU_texture_width(const GPUTexture *tex);
int GPU_texture_height(const GPUTexture *tex);
int GPU_texture_orig_width(const GPUTexture *tex);
diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h
index 2af9929db35..36caee10072 100644
--- a/source/blender/gpu/GPU_vertex_buffer.h
+++ b/source/blender/gpu/GPU_vertex_buffer.h
@@ -139,6 +139,9 @@ GPUVertBufStatus GPU_vertbuf_get_status(const GPUVertBuf *verts);
void GPU_vertbuf_use(GPUVertBuf *);
+/* XXX do not use. */
+void GPU_vertbuf_update_sub(GPUVertBuf *verts, uint start, uint len, void *data);
+
/* Metrics */
uint GPU_vertbuf_get_memory_usage(void);
diff --git a/source/blender/gpu/intern/gpu_capabilities.cc b/source/blender/gpu/intern/gpu_capabilities.cc
index a79ce27ba63..63e29654e1c 100644
--- a/source/blender/gpu/intern/gpu_capabilities.cc
+++ b/source/blender/gpu/intern/gpu_capabilities.cc
@@ -102,6 +102,11 @@ bool GPU_crappy_amd_driver(void)
return GCaps.broken_amd_driver;
}
+bool GPU_shader_image_load_store_support(void)
+{
+ return GCaps.shader_image_load_store_support;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/gpu/intern/gpu_capabilities_private.hh b/source/blender/gpu/intern/gpu_capabilities_private.hh
index a51525fa932..abe5b706a7d 100644
--- a/source/blender/gpu/intern/gpu_capabilities_private.hh
+++ b/source/blender/gpu/intern/gpu_capabilities_private.hh
@@ -42,6 +42,7 @@ struct GPUCapabilities {
int max_textures_geom = 0;
int max_textures_frag = 0;
bool mem_stats_support = false;
+ bool shader_image_load_store_support = false;
/* OpenGL related workarounds. */
bool mip_render_workaround = false;
bool depth_blitting_workaround = false;
@@ -52,4 +53,4 @@ struct GPUCapabilities {
extern GPUCapabilities GCaps;
-} // namespace blender::gpu \ No newline at end of file
+} // namespace blender::gpu
diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh
index bc07bea4bb1..38f94b8dde9 100644
--- a/source/blender/gpu/intern/gpu_context_private.hh
+++ b/source/blender/gpu/intern/gpu_context_private.hh
@@ -46,7 +46,7 @@ class Context {
Shader *shader = NULL;
FrameBuffer *active_fb = NULL;
GPUMatrixState *matrix_state = NULL;
- GPUStateManager *state_manager = NULL;
+ StateManager *state_manager = NULL;
Immediate *imm = NULL;
/**
diff --git a/source/blender/gpu/intern/gpu_debug.cc b/source/blender/gpu/intern/gpu_debug.cc
deleted file mode 100644
index f179a241926..00000000000
--- a/source/blender/gpu/intern/gpu_debug.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup gpu
- */
-
-#include "BLI_compiler_attrs.h"
-#include "BLI_sys_types.h"
-#include "BLI_system.h"
-#include "BLI_utildefines.h"
-
-#include "BKE_global.h"
-
-#include "GPU_debug.h"
-#include "GPU_glew.h"
-#include "intern/gpu_private.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-void GPU_print_error_debug(const char *str)
-{
- if (G.debug & G_DEBUG) {
- fprintf(stderr, "GPU: %s\n", str);
- }
-}
diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc
index 9c3a88e30f0..8d781978857 100644
--- a/source/blender/gpu/intern/gpu_immediate.cc
+++ b/source/blender/gpu/intern/gpu_immediate.cc
@@ -416,7 +416,7 @@ static void immEndVertex(void) /* and move on to the next vertex */
printf("copying %s from vertex %u to %u\n", a->name, imm->vertex_idx - 1, imm->vertex_idx);
#endif
- GLubyte *data = imm->vertex_data + a->offset;
+ uchar *data = imm->vertex_data + a->offset;
memcpy(data, data - imm->vertex_format.stride, a->sz);
/* TODO: consolidate copy of adjacent attributes */
}
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index 769b52bf593..c76ce0f1094 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -28,7 +28,6 @@
#include <string.h>
#include "GPU_framebuffer.h"
-#include "GPU_glew.h"
#include "GPU_immediate.h"
#include "GPU_select.h"
#include "GPU_state.h"
diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh
index f76339d3adb..fce6fda5f14 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.hh
+++ b/source/blender/gpu/intern/gpu_shader_interface.hh
@@ -63,6 +63,7 @@ class ShaderInterface {
/** Enabled bindpoints that needs to be fed with data. */
uint16_t enabled_attr_mask_ = 0;
uint16_t enabled_ubo_mask_ = 0;
+ uint8_t enabled_ima_mask_ = 0;
uint64_t enabled_tex_mask_ = 0;
/** Location of builtin uniforms. Fast access, no lookup needed. */
int32_t builtins_[GPU_NUM_UNIFORMS];
diff --git a/source/blender/gpu/intern/gpu_state.cc b/source/blender/gpu/intern/gpu_state.cc
index be523020e8a..b63abb3d57f 100644
--- a/source/blender/gpu/intern/gpu_state.cc
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -30,7 +30,6 @@
#include "BKE_global.h"
-#include "GPU_glew.h"
#include "GPU_state.h"
#include "gpu_context_private.hh"
@@ -41,7 +40,7 @@ using namespace blender::gpu;
#define SET_STATE(_prefix, _state, _value) \
do { \
- GPUStateManager *stack = Context::get()->state_manager; \
+ StateManager *stack = Context::get()->state_manager; \
auto &state_object = stack->_prefix##state; \
state_object._state = (_value); \
} while (0)
@@ -105,7 +104,7 @@ void GPU_write_mask(eGPUWriteMask mask)
void GPU_color_mask(bool r, bool g, bool b, bool a)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
uint32_t write_mask = state.write_mask;
SET_FLAG_FROM_TEST(write_mask, r, (uint32_t)GPU_WRITE_RED);
@@ -117,7 +116,7 @@ void GPU_color_mask(bool r, bool g, bool b, bool a)
void GPU_depth_mask(bool depth)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
uint32_t write_mask = state.write_mask;
SET_FLAG_FROM_TEST(write_mask, depth, (uint32_t)GPU_WRITE_DEPTH);
@@ -142,7 +141,7 @@ void GPU_state_set(eGPUWriteMask write_mask,
eGPUStencilOp stencil_op,
eGPUProvokingVertex provoking_vert)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::get()->state_manager;
auto &state = stack->state;
state.write_mask = (uint32_t)write_mask;
state.blend = (uint32_t)blend;
@@ -161,7 +160,7 @@ void GPU_state_set(eGPUWriteMask write_mask,
void GPU_depth_range(float near, float far)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::get()->state_manager;
auto &state = stack->mutable_state;
copy_v2_fl2(state.depth_range, near, far);
}
@@ -173,7 +172,7 @@ void GPU_line_width(float width)
void GPU_point_size(float size)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::get()->state_manager;
auto &state = stack->mutable_state;
/* Keep the sign of point_size since it represents the enable state. */
state.point_size = size * ((state.point_size > 0.0) ? 1.0f : -1.0f);
@@ -185,7 +184,7 @@ void GPU_point_size(float size)
/* TODO remove and use program point size everywhere */
void GPU_program_point_size(bool enable)
{
- GPUStateManager *stack = Context::get()->state_manager;
+ StateManager *stack = Context::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);
@@ -306,18 +305,35 @@ void GPU_finish(void)
Context::get()->finish();
}
+void GPU_apply_state(void)
+{
+ Context::get()->state_manager->apply_state();
+}
+
+/* Will set all the states regardless of the current ones. */
+void GPU_force_state(void)
+{
+ Context::get()->state_manager->force_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.
+/** \name Synchronisation Utils
+ * \{ */
+
+void GPU_memory_barrier(eGPUBarrier barrier)
+{
+ Context::get()->state_manager->issue_barrier(barrier);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Default State
* \{ */
-GPUStateManager::GPUStateManager(void)
+StateManager::StateManager(void)
{
/* Set default state. */
state.write_mask = GPU_WRITE_COLOR;
diff --git a/source/blender/gpu/intern/gpu_state_private.hh b/source/blender/gpu/intern/gpu_state_private.hh
index 9fee45e7bd4..b8d247ec175 100644
--- a/source/blender/gpu/intern/gpu_state_private.hh
+++ b/source/blender/gpu/intern/gpu_state_private.hh
@@ -98,9 +98,6 @@ union GPUStateMutable {
/* Viewport State */
/** 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;
@@ -152,21 +149,28 @@ inline GPUStateMutable operator~(const GPUStateMutable &a)
* State manager keeping track of the draw state and applying it before drawing.
* Base class which is then specialized for each implementation (GL, VK, ...).
**/
-class GPUStateManager {
+class StateManager {
public:
GPUState state;
GPUStateMutable mutable_state;
public:
- GPUStateManager();
- virtual ~GPUStateManager(){};
+ StateManager();
+ virtual ~StateManager(){};
virtual void apply_state(void) = 0;
+ virtual void force_state(void) = 0;
+
+ virtual void issue_barrier(eGPUBarrier barrier_bits) = 0;
virtual void texture_bind(Texture *tex, eGPUSamplerState sampler, int unit) = 0;
virtual void texture_unbind(Texture *tex) = 0;
virtual void texture_unbind_all(void) = 0;
+ virtual void image_bind(Texture *tex, int unit) = 0;
+ virtual void image_unbind(Texture *tex) = 0;
+ virtual void image_unbind_all(void) = 0;
+
virtual void texture_unpack_row_length_set(uint len) = 0;
};
diff --git a/source/blender/gpu/intern/gpu_texture.cc b/source/blender/gpu/intern/gpu_texture.cc
index b22fd53f0f6..eb6881164b2 100644
--- a/source/blender/gpu/intern/gpu_texture.cc
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -418,6 +418,21 @@ void GPU_texture_unbind_all(void)
Context::get()->state_manager->texture_unbind_all();
}
+void GPU_texture_image_bind(GPUTexture *tex, int unit)
+{
+ Context::get()->state_manager->image_bind(unwrap(tex), unit);
+}
+
+void GPU_texture_image_unbind(GPUTexture *tex)
+{
+ Context::get()->state_manager->image_unbind(unwrap(tex));
+}
+
+void GPU_texture_image_unbind_all(void)
+{
+ Context::get()->state_manager->image_unbind_all();
+}
+
void GPU_texture_generate_mipmap(GPUTexture *tex)
{
reinterpret_cast<Texture *>(tex)->generate_mipmap();
@@ -498,12 +513,6 @@ void GPU_texture_ref(GPUTexture *tex)
reinterpret_cast<Texture *>(tex)->refcount++;
}
-/* TODO(fclem) Remove! This is broken as it is! */
-int GPU_texture_target(const GPUTexture *UNUSED(tex))
-{
- return GL_TEXTURE_2D;
-}
-
int GPU_texture_width(const GPUTexture *tex)
{
return reinterpret_cast<const Texture *>(tex)->width_get();
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.cc b/source/blender/gpu/intern/gpu_vertex_buffer.cc
index 4cc2af889e6..ea149aaa254 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer.cc
+++ b/source/blender/gpu/intern/gpu_vertex_buffer.cc
@@ -324,4 +324,11 @@ void GPU_vertbuf_use(GPUVertBuf *verts)
unwrap(verts)->upload();
}
+/* XXX this is just a wrapper for the use of the Hair refine workaround.
+ * To be used with GPU_vertbuf_use(). */
+void GPU_vertbuf_update_sub(GPUVertBuf *verts, uint start, uint len, void *data)
+{
+ unwrap(verts)->update_sub(start, len, data);
+}
+
/** \} */ \ No newline at end of file
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
index f1de0a2ac96..3cce7e79857 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
+++ b/source/blender/gpu/intern/gpu_vertex_buffer_private.hh
@@ -95,6 +95,8 @@ class VertBuf {
}
}
+ virtual void update_sub(uint start, uint len, void *data) = 0;
+
protected:
virtual void acquire_data(void) = 0;
virtual void resize_data(void) = 0;
diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc
index ac8439167e3..3b0aa055588 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.cc
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -70,7 +70,7 @@ static uint comp_sz(GPUVertCompType type)
#if TRUST_NO_ONE
assert(type <= GPU_COMP_F32); /* other types have irregular sizes (not bytes) */
#endif
- const GLubyte sizes[] = {1, 1, 2, 2, 4, 4, 4};
+ const uint sizes[] = {1, 1, 2, 2, 4, 4, 4};
return sizes[type];
}
diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc
index edaa84cdcf8..46e048d7f7c 100644
--- a/source/blender/gpu/opengl/gl_backend.cc
+++ b/source/blender/gpu/opengl/gl_backend.cc
@@ -210,6 +210,7 @@ static void detect_workarounds(void)
GLContext::debug_layer_workaround = true;
GLContext::unused_fb_slot_workaround = true;
/* Turn off extensions. */
+ GCaps.shader_image_load_store_support = false;
GLContext::base_instance_support = false;
GLContext::clear_texture_support = false;
GLContext::copy_image_support = false;
@@ -250,17 +251,20 @@ static void detect_workarounds(void)
(strstr(version, "4.5.13399") || strstr(version, "4.5.13417") ||
strstr(version, "4.5.13422"))) {
GLContext::unused_fb_slot_workaround = true;
+ GCaps.shader_image_load_store_support = false;
GCaps.broken_amd_driver = true;
}
/* We have issues with this specific renderer. (see T74024) */
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) &&
strstr(renderer, "AMD VERDE")) {
GLContext::unused_fb_slot_workaround = true;
+ GCaps.shader_image_load_store_support = false;
GCaps.broken_amd_driver = true;
}
/* Fix slowdown on this particular driver. (see T77641) */
if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE) &&
strstr(version, "Mesa 19.3.4")) {
+ GCaps.shader_image_load_store_support = false;
GCaps.broken_amd_driver = true;
}
/* There is an issue with the #glBlitFramebuffer on MacOS with radeon pro graphics.
@@ -349,10 +353,10 @@ static void detect_workarounds(void)
}
/** Internal capabilities. */
-GLint GLContext::max_texture_3d_size;
-GLint GLContext::max_cubemap_size;
-GLint GLContext::max_ubo_size;
-GLint GLContext::max_ubo_binds;
+GLint GLContext::max_cubemap_size = 0;
+GLint GLContext::max_texture_3d_size = 0;
+GLint GLContext::max_ubo_binds = 0;
+GLint GLContext::max_ubo_size = 0;
/** Extensions. */
bool GLContext::base_instance_support = false;
bool GLContext::clear_texture_support = false;
@@ -383,6 +387,7 @@ void GLBackend::capabilities_init(void)
glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &GCaps.max_textures_geom);
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &GCaps.max_textures);
GCaps.mem_stats_support = GLEW_NVX_gpu_memory_info || GLEW_ATI_meminfo;
+ GCaps.shader_image_load_store_support = GLEW_ARB_shader_image_load_store;
/* GL specific capabilities. */
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &GLContext::max_texture_3d_size);
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GLContext::max_cubemap_size);
@@ -413,4 +418,4 @@ void GLBackend::capabilities_init(void)
/** \} */
-} // namespace blender::gpu \ No newline at end of file
+} // namespace blender::gpu
diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh
index 9822c842ce7..4d9c2470db0 100644
--- a/source/blender/gpu/opengl/gl_context.hh
+++ b/source/blender/gpu/opengl/gl_context.hh
@@ -56,8 +56,8 @@ class GLSharedOrphanLists {
class GLContext : public Context {
public:
/** Capabilities. */
- static GLint max_texture_3d_size;
static GLint max_cubemap_size;
+ static GLint max_texture_3d_size;
static GLint max_ubo_size;
static GLint max_ubo_binds;
/** Extensions. */
diff --git a/source/blender/gpu/opengl/gl_debug.cc b/source/blender/gpu/opengl/gl_debug.cc
index de88fdc154c..747d8ee2e3e 100644
--- a/source/blender/gpu/opengl/gl_debug.cc
+++ b/source/blender/gpu/opengl/gl_debug.cc
@@ -200,13 +200,16 @@ void check_gl_resources(const char *info)
* be big enough to feed the data range the shader awaits. */
uint16_t ubo_needed = interface->enabled_ubo_mask_;
ubo_needed &= ~ctx->bound_ubo_slots;
-
/* NOTE: This only check binding. To be valid, the bound texture needs to
* be the same format/target the shader expects. */
uint64_t tex_needed = interface->enabled_tex_mask_;
tex_needed &= ~GLContext::state_manager_active_get()->bound_texture_slots();
+ /* NOTE: This only check binding. To be valid, the bound image needs to
+ * be the same format/target the shader expects. */
+ uint8_t ima_needed = interface->enabled_ima_mask_;
+ ima_needed &= ~GLContext::state_manager_active_get()->bound_image_slots();
- if (ubo_needed == 0 && tex_needed == 0) {
+ if (ubo_needed == 0 && tex_needed == 0 && ima_needed == 0) {
return;
}
@@ -223,6 +226,7 @@ void check_gl_resources(const char *info)
for (int i = 0; tex_needed != 0; i++, tex_needed >>= 1) {
if ((tex_needed & 1) != 0) {
+ /* FIXME: texture_get might return an image input instead. */
const ShaderInput *tex_input = interface->texture_get(i);
const char *tex_name = interface->input_name_get(tex_input);
const char *sh_name = ctx->shader->name_get();
@@ -231,6 +235,18 @@ void check_gl_resources(const char *info)
debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg, NULL);
}
}
+
+ for (int i = 0; ima_needed != 0; i++, ima_needed >>= 1) {
+ if ((ima_needed & 1) != 0) {
+ /* FIXME: texture_get might return a texture input instead. */
+ const ShaderInput *tex_input = interface->texture_get(i);
+ const char *tex_name = interface->input_name_get(tex_input);
+ const char *sh_name = ctx->shader->name_get();
+ char msg[256];
+ SNPRINTF(msg, "Missing Image bind at slot %d : %s > %s : %s", i, sh_name, tex_name, info);
+ debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg, NULL);
+ }
+ }
}
void raise_gl_error(const char *info)
@@ -243,7 +259,7 @@ void raise_gl_error(const char *info)
/* -------------------------------------------------------------------- */
/** \name Object Label
*
- * Useful for debugging through renderdoc. Only defined if using --debug-gpu.
+ * Useful for debugging through render-doc. Only defined if using `--debug-gpu`.
* Make sure to bind the object first so that it gets defined by the GL implementation.
* \{ */
diff --git a/source/blender/gpu/opengl/gl_drawlist.hh b/source/blender/gpu/opengl/gl_drawlist.hh
index 3a731559e3a..5c1e698c0a1 100644
--- a/source/blender/gpu/opengl/gl_drawlist.hh
+++ b/source/blender/gpu/opengl/gl_drawlist.hh
@@ -31,7 +31,6 @@
#include "BLI_sys_types.h"
#include "GPU_batch.h"
-#include "GPU_glew.h"
#include "gpu_drawlist_private.hh"
diff --git a/source/blender/gpu/opengl/gl_shader_interface.cc b/source/blender/gpu/opengl/gl_shader_interface.cc
index d611efcd975..2d55c222e9c 100644
--- a/source/blender/gpu/opengl/gl_shader_interface.cc
+++ b/source/blender/gpu/opengl/gl_shader_interface.cc
@@ -100,6 +100,31 @@ static inline int sampler_binding(int32_t program,
return -1;
}
}
+
+static inline int image_binding(int32_t program,
+ uint32_t uniform_index,
+ int32_t uniform_location,
+ int *image_len)
+{
+ /* Identify image uniforms and asign image units to them. */
+ GLint type;
+ glGetActiveUniformsiv(program, 1, &uniform_index, GL_UNIFORM_TYPE, &type);
+
+ switch (type) {
+ case GL_IMAGE_1D:
+ case GL_IMAGE_2D:
+ case GL_IMAGE_3D: {
+ /* For now just assign a consecutive index. In the future, we should set it in
+ * the shader using layout(binding = i) and query its value. */
+ int binding = *image_len;
+ glUniform1i(uniform_location, binding);
+ (*image_len)++;
+ return binding;
+ }
+ default:
+ return -1;
+ }
+}
/** \} */
/* -------------------------------------------------------------------- */
@@ -207,8 +232,8 @@ GLShaderInterface::GLShaderInterface(GLuint program)
enabled_ubo_mask_ |= (1 << input->binding);
}
- /* Uniforms */
- for (int i = 0, sampler = 0; i < active_uniform_len; i++) {
+ /* Uniforms & samplers & images */
+ for (int i = 0, sampler = 0, image = 0; i < active_uniform_len; i++) {
if (BLI_BITMAP_TEST(uniforms_from_blocks, i)) {
continue;
}
@@ -224,6 +249,12 @@ GLShaderInterface::GLShaderInterface(GLuint program)
name_buffer_offset += this->set_input_name(input, name, name_len);
enabled_tex_mask_ |= (input->binding != -1) ? (1lu << input->binding) : 0lu;
+
+ if (input->binding == -1) {
+ input->binding = image_binding(program, i, input->location, &image);
+
+ enabled_ima_mask_ |= (input->binding != -1) ? (1lu << input->binding) : 0lu;
+ }
}
/* Builtin Uniforms */
@@ -296,4 +327,4 @@ void GLShaderInterface::ref_remove(GLVaoCache *ref)
/** \} */
-} // namespace blender::gpu \ No newline at end of file
+} // namespace blender::gpu
diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc
index 1678760e9cd..cd24fa0e0e4 100644
--- a/source/blender/gpu/opengl/gl_state.cc
+++ b/source/blender/gpu/opengl/gl_state.cc
@@ -42,7 +42,7 @@ namespace blender::gpu {
/** \name GLStateManager
* \{ */
-GLStateManager::GLStateManager(void) : GPUStateManager()
+GLStateManager::GLStateManager(void) : StateManager()
{
/* Set other states that never change. */
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
@@ -76,9 +76,21 @@ void GLStateManager::apply_state(void)
this->set_state(this->state);
this->set_mutable_state(this->mutable_state);
this->texture_bind_apply();
+ this->image_bind_apply();
active_fb->apply_state();
};
+void GLStateManager::force_state(void)
+{
+ /* Little exception for clip distances since they need to keep the old count correct. */
+ uint32_t clip_distances = current_.clip_distances;
+ current_ = ~this->state;
+ current_.clip_distances = clip_distances;
+ current_mutable_ = ~this->mutable_state;
+ this->set_state(this->state);
+ this->set_mutable_state(this->mutable_state);
+};
+
void GLStateManager::set_state(const GPUState &state)
{
GPUState changed = state ^ current_;
@@ -538,4 +550,98 @@ uint64_t GLStateManager::bound_texture_slots(void)
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Image Binding (from image load store)
+ * \{ */
+
+void GLStateManager::image_bind(Texture *tex_, int unit)
+{
+ /* Minimum support is 8 image in the fragment shader. No image for other stages. */
+ BLI_assert(GPU_shader_image_load_store_support() && unit < 8);
+ GLTexture *tex = static_cast<GLTexture *>(tex_);
+ if (G.debug & G_DEBUG_GPU) {
+ tex->check_feedback_loop();
+ }
+ images_[unit] = tex->tex_id_;
+ formats_[unit] = to_gl_internal_format(tex->format_);
+ tex->is_bound_ = true;
+ dirty_image_binds_ |= 1ULL << unit;
+}
+
+void GLStateManager::image_unbind(Texture *tex_)
+{
+ GLTexture *tex = static_cast<GLTexture *>(tex_);
+ if (!tex->is_bound_) {
+ return;
+ }
+
+ GLuint tex_id = tex->tex_id_;
+ for (int i = 0; i < ARRAY_SIZE(images_); i++) {
+ if (images_[i] == tex_id) {
+ images_[i] = 0;
+ dirty_image_binds_ |= 1ULL << i;
+ }
+ }
+ tex->is_bound_ = false;
+}
+
+void GLStateManager::image_unbind_all(void)
+{
+ for (int i = 0; i < ARRAY_SIZE(images_); i++) {
+ if (images_[i] != 0) {
+ images_[i] = 0;
+ dirty_image_binds_ |= 1ULL << i;
+ }
+ }
+ this->image_bind_apply();
+}
+
+void GLStateManager::image_bind_apply(void)
+{
+ if (dirty_image_binds_ == 0) {
+ return;
+ }
+ uint32_t dirty_bind = dirty_image_binds_;
+ dirty_image_binds_ = 0;
+
+ int first = bitscan_forward_uint(dirty_bind);
+ int last = 32 - bitscan_reverse_uint(dirty_bind);
+ int count = last - first;
+
+ if (GLContext::multi_bind_support) {
+ glBindImageTextures(first, count, images_ + first);
+ }
+ else {
+ for (int unit = first; unit < last; unit++) {
+ if ((dirty_bind >> unit) & 1UL) {
+ glBindImageTexture(unit, images_[unit], 0, GL_TRUE, 0, GL_READ_WRITE, formats_[unit]);
+ }
+ }
+ }
+}
+
+uint8_t GLStateManager::bound_image_slots(void)
+{
+ uint8_t bound_slots = 0;
+ for (int i = 0; i < ARRAY_SIZE(images_); i++) {
+ if (images_[i] != 0) {
+ bound_slots |= 1ULL << i;
+ }
+ }
+ return bound_slots;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Memory barrier
+ * \{ */
+
+void GLStateManager::issue_barrier(eGPUBarrier barrier_bits)
+{
+ glMemoryBarrier(to_gl(barrier_bits));
+}
+
+/** \} */
+
} // namespace blender::gpu
diff --git a/source/blender/gpu/opengl/gl_state.hh b/source/blender/gpu/opengl/gl_state.hh
index fb2ed3403f7..cab654006c6 100644
--- a/source/blender/gpu/opengl/gl_state.hh
+++ b/source/blender/gpu/opengl/gl_state.hh
@@ -40,7 +40,7 @@ class GLTexture;
* State manager keeping track of the draw state and applying it before drawing.
* Opengl Implementation.
**/
-class GLStateManager : public GPUStateManager {
+class GLStateManager : public StateManager {
public:
/** Anothter reference to the active framebuffer. */
GLFrameBuffer *active_fb = nullptr;
@@ -64,19 +64,31 @@ class GLStateManager : public GPUStateManager {
GLuint samplers_[64] = {0};
uint64_t dirty_texture_binds_ = 0;
+ GLuint images_[8] = {0};
+ GLenum formats_[8] = {0};
+ uint8_t dirty_image_binds_ = 0;
+
public:
GLStateManager();
void apply_state(void) override;
+ void force_state(void) override;
+
+ void issue_barrier(eGPUBarrier barrier_bits) override;
void texture_bind(Texture *tex, eGPUSamplerState sampler, int unit) override;
void texture_bind_temp(GLTexture *tex);
void texture_unbind(Texture *tex) override;
void texture_unbind_all(void) override;
+ void image_bind(Texture *tex, int unit) override;
+ void image_unbind(Texture *tex) override;
+ void image_unbind_all(void) override;
+
void texture_unpack_row_length_set(uint len) override;
uint64_t bound_texture_slots(void);
+ uint8_t bound_image_slots(void);
private:
static void set_write_mask(const eGPUWriteMask value);
@@ -95,9 +107,22 @@ class GLStateManager : public GPUStateManager {
void set_mutable_state(const GPUStateMutable &state);
void texture_bind_apply(void);
+ void image_bind_apply(void);
MEM_CXX_CLASS_ALLOC_FUNCS("GLStateManager")
};
+static inline GLbitfield to_gl(eGPUBarrier barrier_bits)
+{
+ GLbitfield barrier = 0;
+ if (barrier_bits & GPU_BARRIER_SHADER_IMAGE_ACCESS) {
+ barrier |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
+ }
+ if (barrier_bits & GPU_BARRIER_TEXTURE_FETCH) {
+ barrier |= GL_TEXTURE_FETCH_BARRIER_BIT;
+ }
+ return barrier;
+}
+
} // namespace gpu
} // namespace blender
diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.cc b/source/blender/gpu/opengl/gl_vertex_buffer.cc
index a724c94775e..d97fc2c1600 100644
--- a/source/blender/gpu/opengl/gl_vertex_buffer.cc
+++ b/source/blender/gpu/opengl/gl_vertex_buffer.cc
@@ -106,4 +106,9 @@ void GLVertBuf::bind(void)
}
}
+void GLVertBuf::update_sub(uint start, uint len, void *data)
+{
+ glBufferSubData(GL_ARRAY_BUFFER, start, len, data);
+}
+
} // namespace blender::gpu \ No newline at end of file
diff --git a/source/blender/gpu/opengl/gl_vertex_buffer.hh b/source/blender/gpu/opengl/gl_vertex_buffer.hh
index eee5222f467..e2bf6cd00e8 100644
--- a/source/blender/gpu/opengl/gl_vertex_buffer.hh
+++ b/source/blender/gpu/opengl/gl_vertex_buffer.hh
@@ -45,6 +45,8 @@ class GLVertBuf : public VertBuf {
public:
void bind(void);
+ void update_sub(uint start, uint len, void *data) override;
+
protected:
void acquire_data(void) override;
void resize_data(void) override;
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index ba096653e0f..c7d8a8b3723 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -583,8 +583,8 @@ static void free_posetree(PoseTree *tree)
MEM_freeN(tree);
}
-///----------------------------------------
-/// Plugin API for legacy iksolver
+/* ------------------------------
+ * Plugin API for legacy iksolver */
void iksolver_initialize_tree(struct Depsgraph *UNUSED(depsgraph),
struct Scene *UNUSED(scene),
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp
index 1fbe7b46963..8978b823e2a 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.cpp
+++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp
@@ -247,14 +247,14 @@ void BlockDXT1::setIndices(const int *idx)
}
}
-/// Flip DXT1 block vertically.
+/** Flip DXT1 block vertically. */
inline void BlockDXT1::flip4()
{
swap(row[0], row[3]);
swap(row[1], row[2]);
}
-/// Flip half DXT1 block vertically.
+/** Flip half DXT1 block vertically. */
inline void BlockDXT1::flip2()
{
swap(row[0], row[1]);
@@ -299,27 +299,27 @@ void AlphaBlockDXT3::decodeBlock(ColorBlock *block) const
block->color(0xF).a = (alphaF << 4) | alphaF;
}
-/// Flip DXT3 alpha block vertically.
+/** Flip DXT3 alpha block vertically. */
void AlphaBlockDXT3::flip4()
{
swap(row[0], row[3]);
swap(row[1], row[2]);
}
-/// Flip half DXT3 alpha block vertically.
+/** Flip half DXT3 alpha block vertically. */
void AlphaBlockDXT3::flip2()
{
swap(row[0], row[1]);
}
-/// Flip DXT3 block vertically.
+/** Flip DXT3 block vertically. */
void BlockDXT3::flip4()
{
alpha.flip4();
color.flip4();
}
-/// Flip half DXT3 block vertically.
+/** Flip half DXT3 block vertically. */
void BlockDXT3::flip2()
{
alpha.flip2();
@@ -458,21 +458,21 @@ void BlockDXT5::decodeBlockNV5x(ColorBlock *block) const
alpha.decodeBlock(block);
}
-/// Flip DXT5 block vertically.
+/** Flip DXT5 block vertically. */
void BlockDXT5::flip4()
{
alpha.flip4();
color.flip4();
}
-/// Flip half DXT5 block vertically.
+/** Flip half DXT5 block vertically. */
void BlockDXT5::flip2()
{
alpha.flip2();
color.flip2();
}
-/// Decode ATI1 block.
+/** Decode ATI1 block. */
void BlockATI1::decodeBlock(ColorBlock *block) const
{
uint8 alpha_array[8];
@@ -488,19 +488,19 @@ void BlockATI1::decodeBlock(ColorBlock *block) const
}
}
-/// Flip ATI1 block vertically.
+/** Flip ATI1 block vertically. */
void BlockATI1::flip4()
{
alpha.flip4();
}
-/// Flip half ATI1 block vertically.
+/** Flip half ATI1 block vertically. */
void BlockATI1::flip2()
{
alpha.flip2();
}
-/// Decode ATI2 block.
+/** Decode ATI2 block. */
void BlockATI2::decodeBlock(ColorBlock *block) const
{
uint8 alpha_array[8];
@@ -525,14 +525,14 @@ void BlockATI2::decodeBlock(ColorBlock *block) const
}
}
-/// Flip ATI2 block vertically.
+/** Flip ATI2 block vertically. */
void BlockATI2::flip4()
{
x.flip4();
y.flip4();
}
-/// Flip half ATI2 block vertically.
+/** Flip half ATI2 block vertically. */
void BlockATI2::flip2()
{
x.flip2();
@@ -586,14 +586,14 @@ void BlockCTX1::setIndices(const int *idx)
}
}
-/// Flip CTX1 block vertically.
+/** Flip CTX1 block vertically. */
inline void BlockCTX1::flip4()
{
swap(row[0], row[3]);
swap(row[1], row[2]);
}
-/// Flip half CTX1 block vertically.
+/** Flip half CTX1 block vertically. */
inline void BlockCTX1::flip2()
{
swap(row[0], row[1]);
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h
index 70ec8808c61..83cc147c76c 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.h
+++ b/source/blender/imbuf/intern/dds/BlockDXT.h
@@ -55,7 +55,7 @@
#include <Common.h>
#include <Stream.h>
-/// DXT1 block.
+/** DXT1 block. */
struct BlockDXT1 {
Color16 col0;
Color16 col1;
@@ -81,13 +81,13 @@ struct BlockDXT1 {
void flip2();
};
-/// Return true if the block uses four color mode, false otherwise.
+/** Return true if the block uses four color mode, false otherwise. */
inline bool BlockDXT1::isFourColorMode() const
{
return col0.u > col1.u;
}
-/// DXT3 alpha block with explicit alpha.
+/** DXT3 alpha block with explicit alpha. */
struct AlphaBlockDXT3 {
union {
struct {
@@ -117,7 +117,7 @@ struct AlphaBlockDXT3 {
void flip2();
};
-/// DXT3 block.
+/** DXT3 block. */
struct BlockDXT3 {
AlphaBlockDXT3 alpha;
BlockDXT1 color;
@@ -129,7 +129,7 @@ struct BlockDXT3 {
void flip2();
};
-/// DXT5 alpha block.
+/** DXT5 alpha block. */
struct AlphaBlockDXT5 {
// uint64 unions do not compile on all platforms
#if 0
@@ -245,7 +245,7 @@ struct AlphaBlockDXT5 {
void flip2();
};
-/// DXT5 block.
+/** DXT5 block. */
struct BlockDXT5 {
AlphaBlockDXT5 alpha;
BlockDXT1 color;
@@ -257,7 +257,7 @@ struct BlockDXT5 {
void flip2();
};
-/// ATI1 block.
+/** ATI1 block. */
struct BlockATI1 {
AlphaBlockDXT5 alpha;
@@ -267,7 +267,7 @@ struct BlockATI1 {
void flip2();
};
-/// ATI2 block.
+/** ATI2 block. */
struct BlockATI2 {
AlphaBlockDXT5 x;
AlphaBlockDXT5 y;
@@ -278,7 +278,7 @@ struct BlockATI2 {
void flip2();
};
-/// CTX1 block.
+/** CTX1 block. */
struct BlockCTX1 {
uint8 col0[2];
uint8 col1[2];
diff --git a/source/blender/imbuf/intern/dds/Color.h b/source/blender/imbuf/intern/dds/Color.h
index d0b67d4638c..4a9202617f5 100644
--- a/source/blender/imbuf/intern/dds/Color.h
+++ b/source/blender/imbuf/intern/dds/Color.h
@@ -29,7 +29,7 @@
#pragma once
-/// 32 bit color stored as BGRA.
+/** 32 bit color stored as BGRA. */
class Color32 {
public:
Color32()
@@ -93,7 +93,7 @@ class Color32 {
};
};
-/// 16 bit 565 BGR color.
+/** 16 bit 565 BGR color. */
class Color16 {
public:
Color16()
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.cpp b/source/blender/imbuf/intern/dds/ColorBlock.cpp
index 69757d797b5..f2e8e0b0313 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.cpp
+++ b/source/blender/imbuf/intern/dds/ColorBlock.cpp
@@ -46,12 +46,12 @@ inline static uint colorDistance(Color32 c0, Color32 c1)
}
#endif
-/// Default constructor.
+/** Default constructor. */
ColorBlock::ColorBlock()
{
}
-/// Init the color block from an array of colors.
+/** Init the color block from an array of colors. */
ColorBlock::ColorBlock(const uint *linearImage)
{
for (uint i = 0; i < 16; i++) {
@@ -59,7 +59,7 @@ ColorBlock::ColorBlock(const uint *linearImage)
}
}
-/// Init the color block with the contents of the given block.
+/** Init the color block with the contents of the given block. */
ColorBlock::ColorBlock(const ColorBlock &block)
{
for (uint i = 0; i < 16; i++) {
@@ -67,7 +67,7 @@ ColorBlock::ColorBlock(const ColorBlock &block)
}
}
-/// Initialize this color block.
+/** Initialize this color block. */
ColorBlock::ColorBlock(const Image *img, uint x, uint y)
{
init(img, x, y);
@@ -159,7 +159,7 @@ void ColorBlock::swizzle(uint x, uint y, uint z, uint w)
}
}
-/// Returns true if the block has a single color.
+/** Returns true if the block has a single color. */
bool ColorBlock::isSingleColor(Color32 mask /*= Color32(0xFF, 0xFF, 0xFF, 0x00)*/) const
{
uint u = m_color[0].u & mask.u;
@@ -174,7 +174,7 @@ bool ColorBlock::isSingleColor(Color32 mask /*= Color32(0xFF, 0xFF, 0xFF, 0x00)*
}
#if 0
-/// Returns true if the block has a single color, ignoring transparent pixels.
+/** Returns true if the block has a single color, ignoring transparent pixels. */
bool ColorBlock::isSingleColorNoAlpha() const
{
Color32 c;
@@ -199,7 +199,7 @@ bool ColorBlock::isSingleColorNoAlpha() const
#endif
#if 0
-/// Count number of unique colors in this color block.
+/** Count number of unique colors in this color block. */
uint ColorBlock::countUniqueColors() const
{
uint count = 0;
@@ -223,7 +223,7 @@ uint ColorBlock::countUniqueColors() const
#endif
#if 0
-/// Get average color of the block.
+/** Get average color of the block. */
Color32 ColorBlock::averageColor() const
{
uint r, g, b, a;
@@ -240,7 +240,7 @@ Color32 ColorBlock::averageColor() const
}
#endif
-/// Return true if the block is not fully opaque.
+/** Return true if the block is not fully opaque. */
bool ColorBlock::hasAlpha() const
{
for (uint i = 0; i < 16; i++) {
@@ -253,7 +253,7 @@ bool ColorBlock::hasAlpha() const
#if 0
-/// Get diameter color range.
+/** Get diameter color range. */
void ColorBlock::diameterRange(Color32 *start, Color32 *end) const
{
Color32 c0, c1;
@@ -274,7 +274,7 @@ void ColorBlock::diameterRange(Color32 *start, Color32 *end) const
*end = c1;
}
-/// Get luminance color range.
+/** Get luminance color range. */
void ColorBlock::luminanceRange(Color32 *start, Color32 *end) const
{
Color32 minColor, maxColor;
@@ -299,7 +299,7 @@ void ColorBlock::luminanceRange(Color32 *start, Color32 *end) const
*end = maxColor;
}
-/// Get color range based on the bounding box.
+/** Get color range based on the bounding box. */
void ColorBlock::boundsRange(Color32 *start, Color32 *end) const
{
Color32 minColor(255, 255, 255);
@@ -344,7 +344,7 @@ void ColorBlock::boundsRange(Color32 *start, Color32 *end) const
*end = maxColor;
}
-/// Get color range based on the bounding box.
+/** Get color range based on the bounding box. */
void ColorBlock::boundsRangeAlpha(Color32 *start, Color32 *end) const
{
Color32 minColor(255, 255, 255, 255);
@@ -400,7 +400,7 @@ void ColorBlock::boundsRangeAlpha(Color32 *start, Color32 *end) const
#endif
#if 0
-/// Sort colors by abosolute value in their 16 bit representation.
+/** Sort colors by abosolute value in their 16 bit representation. */
void ColorBlock::sortColorsByAbsoluteValue()
{
// Dummy selection sort.
@@ -422,7 +422,7 @@ void ColorBlock::sortColorsByAbsoluteValue()
#endif
#if 0
-/// Find extreme colors in the given axis.
+/** Find extreme colors in the given axis. */
void ColorBlock::computeRange(Vector3::Arg axis, Color32 *start, Color32 *end) const
{
@@ -452,7 +452,7 @@ void ColorBlock::computeRange(Vector3::Arg axis, Color32 *start, Color32 *end) c
#endif
#if 0
-/// Sort colors in the given axis.
+/** Sort colors in the given axis. */
void ColorBlock::sortColors(const Vector3 &axis)
{
float luma_array[16];
@@ -477,7 +477,7 @@ void ColorBlock::sortColors(const Vector3 &axis)
#endif
#if 0
-/// Get the volume of the color block.
+/** Get the volume of the color block. */
float ColorBlock::volume() const
{
Box bounds;
diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h
index dd63286e230..98b4c9cb40a 100644
--- a/source/blender/imbuf/intern/dds/ColorBlock.h
+++ b/source/blender/imbuf/intern/dds/ColorBlock.h
@@ -32,7 +32,7 @@
#include <Color.h>
#include <Image.h>
-/// Uncompressed 4x4 color block.
+/** Uncompressed 4x4 color block. */
struct ColorBlock {
ColorBlock();
ColorBlock(const uint *linearImage);
@@ -61,31 +61,31 @@ struct ColorBlock {
Color32 m_color[4 * 4];
};
-/// Get pointer to block colors.
+/** Get pointer to block colors. */
inline const Color32 *ColorBlock::colors() const
{
return m_color;
}
-/// Get block color.
+/** Get block color. */
inline Color32 ColorBlock::color(uint i) const
{
return m_color[i];
}
-/// Get block color.
+/** Get block color. */
inline Color32 &ColorBlock::color(uint i)
{
return m_color[i];
}
-/// Get block color.
+/** Get block color. */
inline Color32 ColorBlock::color(uint x, uint y) const
{
return m_color[y * 4 + x];
}
-/// Get block color.
+/** Get block color. */
inline Color32 &ColorBlock::color(uint x, uint y)
{
return m_color[y * 4 + x];
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
index ac7f893fddd..373d5974a5e 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h
@@ -73,7 +73,7 @@ struct DDSCaps {
uint caps4;
};
-/// DDS file header for DX10.
+/** DDS file header for DX10. */
struct DDSHeader10 {
uint dxgiFormat;
uint resourceDimension;
@@ -82,7 +82,7 @@ struct DDSHeader10 {
uint reserved;
};
-/// DDS file header.
+/** DDS file header. */
struct DDSHeader {
uint fourcc;
uint size;
@@ -132,7 +132,7 @@ struct DDSHeader {
uint d3d9Format() const;
};
-/// DirectDraw Surface. (DDS)
+/** DirectDraw Surface. (DDS) */
class DirectDrawSurface {
public:
DirectDrawSurface(unsigned char *mem, uint size);
diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h
index 4ccfec99445..0f977641d89 100644
--- a/source/blender/imbuf/intern/dds/Image.h
+++ b/source/blender/imbuf/intern/dds/Image.h
@@ -32,7 +32,7 @@
#include "Color.h"
#include "Common.h"
-/// 32 bit RGBA image.
+/** 32 bit RGBA image. */
class Image {
public:
enum Format {
diff --git a/source/blender/makesdna/DNA_image_defaults.h b/source/blender/makesdna/DNA_image_defaults.h
index ce1296d681f..93ff8792dfa 100644
--- a/source/blender/makesdna/DNA_image_defaults.h
+++ b/source/blender/makesdna/DNA_image_defaults.h
@@ -36,6 +36,8 @@
.gen_type = IMA_GENTYPE_GRID, \
\
.gpuframenr = INT_MAX, \
+ .gpu_pass = SHRT_MAX, \
+ .gpu_layer = SHRT_MAX, \
}
/** \} */
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index 749bc55fcb9..4a05d7ba319 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -147,9 +147,11 @@ typedef struct Image {
int lastframe;
/* GPU texture flag. */
- short gpuflag;
- char _pad2[2];
int gpuframenr;
+ short gpuflag;
+ short gpu_pass;
+ short gpu_layer;
+ char _pad2[6];
/** Deprecated. */
struct PackedFile *packedfile DNA_DEPRECATED;
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index a4b379bff15..c92665d4ac2 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -623,9 +623,10 @@ typedef struct UserDef_Experimental {
char use_new_hair_type;
char use_cycles_debug;
char use_sculpt_vertex_colors;
+ char use_image_editor_legacy_drawing;
char use_tools_missing_icons;
/** `makesdna` does not allow empty structs. */
- char _pad[2];
+ char _pad[1];
} UserDef_Experimental;
#define USER_EXPERIMENTAL_TEST(userdef, member) \
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 0387f83d695..976035b9886 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -385,10 +385,6 @@ blender_include_dirs(
../../../../intern/mantaflow/extern
)
-blender_include_dirs_sys(
- "${GLEW_INCLUDE_PATH}"
-)
-
add_cc_flags_custom_test(makesrna)
setup_platform_linker_flags()
@@ -443,7 +439,6 @@ set(LIB
bf_editor_undo
)
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_rna "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index eab6349317a..13b068c2be5 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -243,35 +243,87 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu
}
}
+/* Helper function which returns index of the given hair_key in particle which owns it.
+ * Works with cases when hair_key is coming from the particle which was passed here, and from the
+ * original particle of the given one.
+ *
+ * Such trickery is needed to allow modification of hair keys in the original object using
+ * evaluated particle and object to access proper hair matrix. */
+static int hair_key_index_get(/*const*/ HairKey *hair_key,
+ /*const*/ ParticleSystemModifierData *modifier,
+ /*const*/ ParticleData *particle)
+{
+ if (ARRAY_HAS_ITEM(hair_key, particle->hair, particle->totkey)) {
+ return hair_key - particle->hair;
+ }
+
+ const ParticleSystem *particle_system = modifier->psys;
+ const int particle_index = particle - particle_system->particles;
+
+ const ParticleSystemModifierData *original_modifier = (ParticleSystemModifierData *)
+ BKE_modifier_get_original(&modifier->modifier);
+ const ParticleSystem *original_particle_system = original_modifier->psys;
+ const ParticleData *original_particle = &original_particle_system->particles[particle_index];
+
+ if (ARRAY_HAS_ITEM(hair_key, original_particle->hair, original_particle->totkey)) {
+ return hair_key - original_particle->hair;
+ }
+
+ return -1;
+}
+
+/* Set hair_key->co to the given coordinate in object space (the given coordinate will be
+ * converted to the proper space).
+ *
+ * The hair_key can be coming from both original and evaluated object. Object, modifier and
+ * particle are to be from evaluated object, so that all the data needed for hair matrix is
+ * present. */
+static void hair_key_location_object_set(HairKey *hair_key,
+ Object *object,
+ ParticleSystemModifierData *modifier,
+ ParticleData *particle,
+ const float src_co[3])
+{
+ Mesh *hair_mesh = (modifier->psys->flag & PSYS_HAIR_DYNAMICS) ? modifier->psys->hair_out_mesh :
+ NULL;
+
+ if (hair_mesh != NULL) {
+ const int hair_key_index = hair_key_index_get(hair_key, modifier, particle);
+ if (hair_key_index == -1) {
+ return;
+ }
+
+ MVert *mvert = &hair_mesh->mvert[particle->hair_index + (hair_key_index)];
+ copy_v3_v3(mvert->co, src_co);
+ return;
+ }
+
+ float hairmat[4][4];
+ psys_mat_hair_to_object(
+ object, modifier->mesh_final, modifier->psys->part->from, particle, hairmat);
+
+ float imat[4][4];
+ invert_m4_m4(imat, hairmat);
+
+ copy_v3_v3(hair_key->co, src_co);
+ mul_m4_v3(imat, hair_key->co);
+}
+
static void rna_ParticleHairKey_location_object_set(PointerRNA *ptr, const float *values)
{
HairKey *hkey = (HairKey *)ptr->data;
Object *ob = (Object *)ptr->owner_id;
+
ParticleSystemModifierData *psmd;
ParticleData *pa;
-
rna_ParticleHairKey_location_object_info(ptr, &psmd, &pa);
- if (pa) {
- Mesh *hair_mesh = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_mesh : NULL;
-
- if (hair_mesh) {
- MVert *mvert = &hair_mesh->mvert[pa->hair_index + (hkey - pa->hair)];
- copy_v3_v3(mvert->co, values);
- }
- else {
- float hairmat[4][4];
- float imat[4][4];
-
- psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat);
- invert_m4_m4(imat, hairmat);
- copy_v3_v3(hkey->co, values);
- mul_m4_v3(imat, hkey->co);
- }
- }
- else {
+ if (pa == NULL) {
zero_v3(hkey->co);
+ return;
}
+
+ hair_key_location_object_set(hkey, ob, psmd, pa, values);
}
static void rna_ParticleHairKey_co_object(HairKey *hairkey,
@@ -301,6 +353,31 @@ static void rna_ParticleHairKey_co_object(HairKey *hairkey,
}
}
+static void rna_ParticleHairKey_co_object_set(ID *id,
+ HairKey *hair_key,
+ Object *object,
+ ParticleSystemModifierData *modifier,
+ ParticleData *particle,
+ float co[3])
+{
+
+ if (particle == NULL) {
+ return;
+ }
+
+ /* Mark particle system as edited, so then particle_system_update() does not reset the hair
+ * keys from path. This behavior is similar to how particle edit mode sets flags. */
+ ParticleSystemModifierData *orig_modifier = (ParticleSystemModifierData *)
+ modifier->modifier.orig_modifier_data;
+ orig_modifier->psys->flag |= PSYS_EDITED;
+
+ hair_key_location_object_set(hair_key, object, modifier, particle, co);
+
+ /* Tag similar to brushes in particle edit mode, so the modifier stack is properly evaluated
+ * with the same particle system recalc flags as during combing. */
+ DEG_id_tag_update(id, ID_RECALC_GEOMETRY | ID_RECALC_PSYS_REDO);
+}
+
static void rna_Particle_uv_on_emitter(ParticleData *particle,
ReportList *reports,
ParticleSystemModifierData *modifier,
@@ -1651,6 +1728,19 @@ static void rna_def_particle_hair_key(BlenderRNA *brna)
func, "co", 3, NULL, -FLT_MAX, FLT_MAX, "Co", "Exported hairkey location", -1e4, 1e4);
RNA_def_parameter_flags(parm, PROP_THICK_WRAP, 0);
RNA_def_function_output(func, parm);
+
+ func = RNA_def_function(srna, "co_object_set", "rna_ParticleHairKey_co_object_set");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Set hairkey location with particle and modifier data");
+ parm = RNA_def_pointer(func, "object", "Object", "", "Object");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_pointer(func, "modifier", "ParticleSystemModifier", "", "Particle modifier");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_pointer(func, "particle", "Particle", "", "hair particle");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_float_vector(
+ func, "co", 3, NULL, -FLT_MAX, FLT_MAX, "Co", "Specified hairkey location", -1e4, 1e4);
+ RNA_def_parameter_flags(parm, PROP_THICK_WRAP, PARM_REQUIRED);
}
static void rna_def_particle_key(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 1a911494f09..13b316a9d5d 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -2617,9 +2617,10 @@ static void rna_FileBrowser_FSMenu_active_range(PointerRNA *UNUSED(ptr),
*max = *softmax = ED_fsmenu_get_nentries(fsmenu, category) - 1;
}
-static void rna_FileBrowser_FSMenu_active_update(struct bContext *C, PointerRNA *UNUSED(ptr))
+static void rna_FileBrowser_FSMenu_active_update(struct bContext *C, PointerRNA *ptr)
{
- ED_file_change_dir(C);
+ ScrArea *area = rna_area_from_space(ptr);
+ ED_file_change_dir_ex(C, (bScreen *)ptr->owner_id, area);
}
static int rna_FileBrowser_FSMenuSystem_active_get(PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 99f0f53907e..0cbad9fb0c8 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -3066,6 +3066,11 @@ static void rna_def_userdef_theme_space_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Metadata Text", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+ prop = RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Grid", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
+
rna_def_userdef_theme_spaces_curves(srna, false, false, false, true);
rna_def_userdef_theme_spaces_paint_curves(srna);
@@ -6123,6 +6128,11 @@ static void rna_def_userdef_experimental(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "use_sculpt_vertex_colors", 1);
RNA_def_property_ui_text(prop, "Sculpt Vertex Colors", "Use the new Vertex Painting system");
+ prop = RNA_def_property(srna, "use_image_editor_legacy_drawing", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "use_image_editor_legacy_drawing", 1);
+ RNA_def_property_ui_text(
+ prop, "Legacy Image Editor Drawing", "Use legacy UV/Image editor drawing");
+
prop = RNA_def_property(srna, "use_tools_missing_icons", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "use_tools_missing_icons", 1);
RNA_def_property_ui_text(prop, "Tools with Missing Icons", "Show tools with missing icons");
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 01770abeca0..7f65e72bf3e 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -178,7 +178,6 @@ if(WITH_GMP)
endif()
# So we can have special tricks in modifier system.
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_modifiers "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/modifiers/intern/MOD_meshcache_mdd.c b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
index cb150976ff5..d216c14ab43 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_mdd.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
@@ -65,13 +65,13 @@ static bool meshcache_read_mdd_head(FILE *fp,
*err_str = "Invalid frame total";
return false;
}
- /* intentionally dont seek back */
+ /* Intentionally don't seek back. */
return true;
}
/**
- * Gets the index frange and factor
+ * Gets the index range and factor.
*/
static bool meshcache_read_mdd_range(FILE *fp,
const int verts_tot,
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 33b95d50cc0..4172dc06a9f 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -41,9 +41,6 @@ set(INC
../../../intern/sky/include
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
composite/nodes/node_composite_alphaOver.c
@@ -343,7 +340,6 @@ if(WITH_COMPOSITOR)
add_definitions(-DWITH_COMPOSITOR)
endif()
-add_definitions(${GL_DEFINITIONS})
if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c
index 89fe9f8c6aa..8a5c4f4a11b 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -27,12 +27,12 @@
#include <Python.h>
#include "BLI_utildefines.h"
-
-#include "GPU_glew.h"
#include "MEM_guardedalloc.h"
#include "../generic/py_capi_utils.h"
+#include "glew-mx.h"
+
#include "bgl.h"
/* -------------------------------------------------------------------- */
diff --git a/source/blender/python/gpu/gpu_py_offscreen.c b/source/blender/python/gpu/gpu_py_offscreen.c
index 15c39de990b..31440dadd03 100644
--- a/source/blender/python/gpu/gpu_py_offscreen.c
+++ b/source/blender/python/gpu/gpu_py_offscreen.c
@@ -157,6 +157,7 @@ static PyObject *bpygpu_offscreen_bind(BPyGPUOffScreen *self, PyObject *args, Py
}
GPU_offscreen_bind(self->ofs, save);
+ GPU_apply_state();
self->is_saved = save;
Py_INCREF(self);
@@ -185,6 +186,7 @@ static PyObject *bpygpu_offscreen_unbind(BPyGPUOffScreen *self, PyObject *args,
}
GPU_offscreen_unbind(self->ofs, restore);
+ GPU_apply_state();
Py_RETURN_NONE;
}
diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c
index f9ff0558570..55753e91f14 100644
--- a/source/blender/python/gpu/gpu_py_shader.c
+++ b/source/blender/python/gpu/gpu_py_shader.c
@@ -607,12 +607,12 @@ PyDoc_STRVAR(
" ``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"
+ " To debug shaders, use the ``--debug-gpu-shaders`` command line option "
+ "to see full GLSL shader compilation and linking errors.\n"
"\n"
" For drawing user interface elements and gizmos, use "
- " ``fragOutput = blender_srgb_to_framebuffer_space(fragOutput)``"
- " to transform the output sRGB colors to the framebuffer colorspace."
+ "``fragOutput = blender_srgb_to_framebuffer_space(fragOutput)`` "
+ "to transform the output sRGB colors to the frame-buffer color-space."
"\n"
" :param vertexcode: Vertex shader code.\n"
" :type vertexcode: str\n"
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index 6c3f422d3f0..febb0d1cad5 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -341,6 +341,5 @@ if(WITH_XR_OPENXR)
add_definitions(-DWITH_XR_OPENXR)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_python "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/python/intern/bpy_rna_ui.c b/source/blender/python/intern/bpy_rna_ui.c
index 9f37b8300db..27e4cb069ce 100644
--- a/source/blender/python/intern/bpy_rna_ui.c
+++ b/source/blender/python/intern/bpy_rna_ui.c
@@ -29,6 +29,7 @@
#include "UI_interface.h"
#include "bpy_rna.h"
+#include "bpy_rna_ui.h"
PyDoc_STRVAR(bpy_rna_uilayout_introspect_doc,
".. method:: introspect()\n"
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index e3c3cf712f9..2652ec2f8cb 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -39,9 +39,6 @@ set(INC
../../../intern/mantaflow/extern
)
-set(INC_SYS
- ${GLEW_INCLUDE_PATH}
-)
set(SRC
intern/source/bake_api.c
@@ -108,6 +105,5 @@ if(APPLE)
endif()
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib_nolist(bf_render "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/shader_fx/CMakeLists.txt b/source/blender/shader_fx/CMakeLists.txt
index a12f36f9713..a68b343d416 100644
--- a/source/blender/shader_fx/CMakeLists.txt
+++ b/source/blender/shader_fx/CMakeLists.txt
@@ -67,6 +67,5 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_shader_fx "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index 7c749c60168..b9efc0e386a 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -46,7 +46,6 @@ set(INC
set(INC_SYS
${ZLIB_INCLUDE_DIRS}
- ${GLEW_INCLUDE_PATH}
)
set(SRC
@@ -131,7 +130,6 @@ if(WITH_AUDASPACE)
)
endif()
-add_definitions(${GL_DEFINITIONS})
if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 1d3db3e7609..eb5f8ca5ef1 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -396,9 +396,6 @@ static void wm_draw_offscreen_texture_parameters(GPUOffScreen *offscreen)
/* Setup offscreen color texture for drawing. */
GPUTexture *texture = GPU_offscreen_color_texture(offscreen);
- /* We don't support multisample textures here. */
- BLI_assert(GPU_texture_target(texture) == GL_TEXTURE_2D);
-
/* No mipmaps or filtering. */
GPU_texture_mipmap_mode(texture, false, false);
}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index b85bf8cb323..5a22e990218 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -190,8 +190,6 @@ void WM_init_opengl(void)
GPU_pass_cache_init();
- BKE_subdiv_init();
-
opengl_is_init = true;
}
@@ -323,6 +321,8 @@ void WM_init(bContext *C, int argc, const char **argv)
UI_init();
}
+ BKE_subdiv_init();
+
ED_spacemacros_init();
/* note: there is a bug where python needs initializing before loading the
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index d00285adb02..2798cec8c58 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -51,9 +51,6 @@ if(WITH_TBB)
list(INSERT LIB 0 bf_blenkernel)
endif()
-add_definitions(${GL_DEFINITIONS})
-blender_include_dirs("${GLEW_INCLUDE_PATH}")
-
if(WIN32)
blender_include_dirs(../../intern/utfconv)
endif()